diff options
Diffstat (limited to 'tools/testing/ktest/ktest.pl')
-rw-r--r-- | tools/testing/ktest/ktest.pl | 461 |
1 files changed, 319 insertions, 142 deletions
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index ff6283a44847..1f28c45f15b8 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl | |||
@@ -16,28 +16,45 @@ $#ARGV >= 0 || die "usage: autotest.pl config-file\n"; | |||
16 | $| = 1; | 16 | $| = 1; |
17 | 17 | ||
18 | my %opt; | 18 | my %opt; |
19 | my %default; | ||
19 | 20 | ||
20 | #default opts | 21 | #default opts |
21 | $opt{"NUM_BUILDS"} = 5; | 22 | $default{"NUM_TESTS"} = 5; |
22 | $opt{"BUILD_TYPE"} = "randconfig"; | 23 | $default{"REBOOT_TYPE"} = "grub"; |
23 | $opt{"MAKE_CMD"} = "make"; | 24 | $default{"TEST_TYPE"} = "test"; |
24 | $opt{"TIMEOUT"} = 120; | 25 | $default{"BUILD_TYPE"} = "randconfig"; |
25 | $opt{"TMP_DIR"} = "/tmp/autotest"; | 26 | $default{"MAKE_CMD"} = "make"; |
26 | $opt{"SLEEP_TIME"} = 60; # sleep time between tests | 27 | $default{"TIMEOUT"} = 120; |
27 | $opt{"BUILD_NOCLEAN"} = 0; | 28 | $default{"TMP_DIR"} = "/tmp/autotest"; |
28 | $opt{"REBOOT_ON_ERROR"} = 0; | 29 | $default{"SLEEP_TIME"} = 60; # sleep time between tests |
29 | $opt{"POWEROFF_ON_ERROR"} = 0; | 30 | $default{"BUILD_NOCLEAN"} = 0; |
30 | $opt{"REBOOT_ON_SUCCESS"} = 1; | 31 | $default{"REBOOT_ON_ERROR"} = 0; |
31 | $opt{"POWEROFF_ON_SUCCESS"} = 0; | 32 | $default{"POWEROFF_ON_ERROR"} = 0; |
32 | $opt{"BUILD_OPTIONS"} = ""; | 33 | $default{"REBOOT_ON_SUCCESS"} = 1; |
33 | $opt{"BISECT_SLEEP_TIME"} = 10; # sleep time between bisects | 34 | $default{"POWEROFF_ON_SUCCESS"} = 0; |
34 | $opt{"CLEAR_LOG"} = 0; | 35 | $default{"BUILD_OPTIONS"} = ""; |
35 | $opt{"SUCCESS_LINE"} = "login:"; | 36 | $default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects |
36 | $opt{"BOOTED_TIMEOUT"} = 1; | 37 | $default{"CLEAR_LOG"} = 0; |
37 | $opt{"DIE_ON_FAILURE"} = 1; | 38 | $default{"SUCCESS_LINE"} = "login:"; |
39 | $default{"BOOTED_TIMEOUT"} = 1; | ||
40 | $default{"DIE_ON_FAILURE"} = 1; | ||
38 | 41 | ||
39 | my $version; | 42 | my $version; |
43 | my $machine; | ||
44 | my $tmpdir; | ||
45 | my $builddir; | ||
46 | my $outputdir; | ||
47 | my $test_type; | ||
40 | my $build_type; | 48 | my $build_type; |
49 | my $build_options; | ||
50 | my $reboot_type; | ||
51 | my $reboot_script; | ||
52 | my $power_cycle; | ||
53 | my $reboot_on_error; | ||
54 | my $poweroff_on_error; | ||
55 | my $die_on_failure; | ||
56 | my $power_off; | ||
57 | my $grub_menu; | ||
41 | my $grub_number; | 58 | my $grub_number; |
42 | my $target; | 59 | my $target; |
43 | my $make; | 60 | my $make; |
@@ -55,6 +72,16 @@ my $dmesg; | |||
55 | my $monitor_fp; | 72 | my $monitor_fp; |
56 | my $monitor_pid; | 73 | my $monitor_pid; |
57 | my $monitor_cnt = 0; | 74 | my $monitor_cnt = 0; |
75 | my $sleep_time; | ||
76 | my $bisect_sleep_time; | ||
77 | my $store_failures; | ||
78 | my $timeout; | ||
79 | my $booted_timeout; | ||
80 | my $console; | ||
81 | my $success_line; | ||
82 | my $build_target; | ||
83 | my $target_image; | ||
84 | my $localversion; | ||
58 | 85 | ||
59 | sub read_config { | 86 | sub read_config { |
60 | my ($config) = @_; | 87 | my ($config) = @_; |
@@ -70,11 +97,22 @@ sub read_config { | |||
70 | my $lvalue = $1; | 97 | my $lvalue = $1; |
71 | my $rvalue = $2; | 98 | my $rvalue = $2; |
72 | 99 | ||
100 | if (defined($opt{$lvalue})) { | ||
101 | die "Error: Option $lvalue defined more than once!\n"; | ||
102 | } | ||
73 | $opt{$lvalue} = $rvalue; | 103 | $opt{$lvalue} = $rvalue; |
74 | } | 104 | } |
75 | } | 105 | } |
76 | 106 | ||
77 | close(IN); | 107 | close(IN); |
108 | |||
109 | # set any defaults | ||
110 | |||
111 | foreach my $default (keys %default) { | ||
112 | if (!defined($opt{$default})) { | ||
113 | $opt{$default} = $default{$default}; | ||
114 | } | ||
115 | } | ||
78 | } | 116 | } |
79 | 117 | ||
80 | sub logit { | 118 | sub logit { |
@@ -96,20 +134,20 @@ sub reboot { | |||
96 | # try to reboot normally | 134 | # try to reboot normally |
97 | if (!run_command "ssh $target reboot") { | 135 | if (!run_command "ssh $target reboot") { |
98 | # nope? power cycle it. | 136 | # nope? power cycle it. |
99 | run_command "$opt{POWER_CYCLE}"; | 137 | run_command "$power_cycle"; |
100 | } | 138 | } |
101 | } | 139 | } |
102 | 140 | ||
103 | sub dodie { | 141 | sub dodie { |
104 | doprint "CRITICAL FAILURE... ", @_, "\n"; | 142 | doprint "CRITICAL FAILURE... ", @_, "\n"; |
105 | 143 | ||
106 | if ($opt{"REBOOT_ON_ERROR"}) { | 144 | if ($reboot_on_error && $test_type ne "build") { |
107 | doprint "REBOOTING\n"; | 145 | doprint "REBOOTING\n"; |
108 | reboot; | 146 | reboot; |
109 | 147 | ||
110 | } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) { | 148 | } elsif ($poweroff_on_error && defined($power_off)) { |
111 | doprint "POWERING OFF\n"; | 149 | doprint "POWERING OFF\n"; |
112 | `$opt{"POWER_OFF"}`; | 150 | `$power_off`; |
113 | } | 151 | } |
114 | 152 | ||
115 | die @_; | 153 | die @_; |
@@ -120,8 +158,8 @@ sub open_console { | |||
120 | 158 | ||
121 | my $flags; | 159 | my $flags; |
122 | 160 | ||
123 | my $pid = open($fp, "$opt{CONSOLE}|") or | 161 | my $pid = open($fp, "$console|") or |
124 | dodie "Can't open console $opt{CONSOLE}"; | 162 | dodie "Can't open console $console"; |
125 | 163 | ||
126 | $flags = fcntl($fp, F_GETFL, 0) or | 164 | $flags = fcntl($fp, F_GETFL, 0) or |
127 | dodie "Can't get flags for the socket: $!\n"; | 165 | dodie "Can't get flags for the socket: $!\n"; |
@@ -147,6 +185,10 @@ sub start_monitor { | |||
147 | } | 185 | } |
148 | $monitor_fp = \*MONFD; | 186 | $monitor_fp = \*MONFD; |
149 | $monitor_pid = open_console $monitor_fp; | 187 | $monitor_pid = open_console $monitor_fp; |
188 | |||
189 | return; | ||
190 | |||
191 | open(MONFD, "Stop perl from warning about single use of MONFD"); | ||
150 | } | 192 | } |
151 | 193 | ||
152 | sub end_monitor { | 194 | sub end_monitor { |
@@ -160,43 +202,50 @@ sub wait_for_monitor { | |||
160 | my ($time) = @_; | 202 | my ($time) = @_; |
161 | my $line; | 203 | my $line; |
162 | 204 | ||
163 | doprint "Wait for monitor to settle down.\n"; | 205 | doprint "** Wait for monitor to settle down **\n"; |
164 | 206 | ||
165 | # read the monitor and wait for the system to calm down | 207 | # read the monitor and wait for the system to calm down |
166 | do { | 208 | do { |
167 | $line = wait_for_input($monitor_fp, $time); | 209 | $line = wait_for_input($monitor_fp, $time); |
210 | print "$line" if (defined($line)); | ||
168 | } while (defined($line)); | 211 | } while (defined($line)); |
212 | print "** Monitor flushed **\n"; | ||
169 | } | 213 | } |
170 | 214 | ||
171 | sub fail { | 215 | sub fail { |
172 | 216 | ||
173 | if ($opt{"DIE_ON_FAILURE"}) { | 217 | if ($die_on_failure) { |
174 | dodie @_; | 218 | dodie @_; |
175 | } | 219 | } |
176 | 220 | ||
177 | doprint "Failed: ", @_, "\n"; | 221 | doprint "FAILED\n"; |
178 | 222 | ||
179 | doprint "REBOOTING\n"; | 223 | # no need to reboot for just building. |
180 | reboot; | 224 | if ($test_type ne "build") { |
181 | start_monitor; | 225 | doprint "REBOOTING\n"; |
182 | wait_for_monitor $opt{"SLEEP_TIME"}; | 226 | reboot; |
183 | end_monitor; | 227 | start_monitor; |
228 | wait_for_monitor $sleep_time; | ||
229 | end_monitor; | ||
230 | } | ||
184 | 231 | ||
185 | return 1 if (!defined($opt{"STORE_FAILURES"})); | 232 | doprint "**** Failed: ", @_, " ****\n"; |
233 | |||
234 | return 1 if (!defined($store_failures)); | ||
186 | 235 | ||
187 | my @t = localtime; | 236 | my @t = localtime; |
188 | my $date = sprintf "%04d%02d%02d%02d%02d%02d", | 237 | my $date = sprintf "%04d%02d%02d%02d%02d%02d", |
189 | 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; | 238 | 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; |
190 | 239 | ||
191 | my $dir = "$opt{MACHINE}-$build_type-fail-$date"; | 240 | my $dir = "$machine-$test_type-$build_type-fail-$date"; |
192 | my $faildir = "$opt{STORE_FAILURES}/$dir"; | 241 | my $faildir = "$store_failures/$dir"; |
193 | 242 | ||
194 | if (!-d $faildir) { | 243 | if (!-d $faildir) { |
195 | mkpath($faildir) or | 244 | mkpath($faildir) or |
196 | die "can't create $opt{STORE_FAILURES}"; | 245 | die "can't create $faildir"; |
197 | } | 246 | } |
198 | if (-f "$opt{OUTPUT_DIR}/.config") { | 247 | if (-f "$outputdir/.config") { |
199 | cp "$opt{OUTPUT_DIR}/.config", "$faildir/config" or | 248 | cp "$outputdir/.config", "$faildir/config" or |
200 | die "failed to copy .config"; | 249 | die "failed to copy .config"; |
201 | } | 250 | } |
202 | if (-f $buildlog) { | 251 | if (-f $buildlog) { |
@@ -259,6 +308,9 @@ sub run_command { | |||
259 | 308 | ||
260 | sub get_grub_index { | 309 | sub get_grub_index { |
261 | 310 | ||
311 | if ($reboot_type ne "grub") { | ||
312 | return; | ||
313 | } | ||
262 | return if (defined($grub_number)); | 314 | return if (defined($grub_number)); |
263 | 315 | ||
264 | doprint "Find grub menu ... "; | 316 | doprint "Find grub menu ... "; |
@@ -266,7 +318,7 @@ sub get_grub_index { | |||
266 | open(IN, "ssh $target cat /boot/grub/menu.lst |") | 318 | open(IN, "ssh $target cat /boot/grub/menu.lst |") |
267 | or die "unable to get menu.lst"; | 319 | or die "unable to get menu.lst"; |
268 | while (<IN>) { | 320 | while (<IN>) { |
269 | if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) { | 321 | if (/^\s*title\s+$grub_menu\s*$/) { |
270 | $grub_number++; | 322 | $grub_number++; |
271 | last; | 323 | last; |
272 | } elsif (/^\s*title\s/) { | 324 | } elsif (/^\s*title\s/) { |
@@ -275,13 +327,11 @@ sub get_grub_index { | |||
275 | } | 327 | } |
276 | close(IN); | 328 | close(IN); |
277 | 329 | ||
278 | die "Could not find '$opt{GRUB_MENU}' in /boot/grub/menu on $opt{MACHINE}" | 330 | die "Could not find '$grub_menu' in /boot/grub/menu on $machine" |
279 | if ($grub_number < 0); | 331 | if ($grub_number < 0); |
280 | doprint "$grub_number\n"; | 332 | doprint "$grub_number\n"; |
281 | } | 333 | } |
282 | 334 | ||
283 | my $timeout = $opt{"TIMEOUT"}; | ||
284 | |||
285 | sub wait_for_input | 335 | sub wait_for_input |
286 | { | 336 | { |
287 | my ($fp, $time) = @_; | 337 | my ($fp, $time) = @_; |
@@ -314,7 +364,12 @@ sub wait_for_input | |||
314 | } | 364 | } |
315 | 365 | ||
316 | sub reboot_to { | 366 | sub reboot_to { |
317 | run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; | 367 | if ($reboot_type eq "grub") { |
368 | run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; | ||
369 | return; | ||
370 | } | ||
371 | |||
372 | run_command "$reboot_script"; | ||
318 | } | 373 | } |
319 | 374 | ||
320 | sub monitor { | 375 | sub monitor { |
@@ -336,7 +391,7 @@ sub monitor { | |||
336 | for (;;) { | 391 | for (;;) { |
337 | 392 | ||
338 | if ($booted) { | 393 | if ($booted) { |
339 | $line = wait_for_input($monitor_fp, $opt{"BOOTED_TIMEOUT"}); | 394 | $line = wait_for_input($monitor_fp, $booted_timeout); |
340 | } else { | 395 | } else { |
341 | $line = wait_for_input($monitor_fp); | 396 | $line = wait_for_input($monitor_fp); |
342 | } | 397 | } |
@@ -349,7 +404,7 @@ sub monitor { | |||
349 | # we are not guaranteed to get a full line | 404 | # we are not guaranteed to get a full line |
350 | $full_line .= $line; | 405 | $full_line .= $line; |
351 | 406 | ||
352 | if ($full_line =~ /$opt{"SUCCESS_LINE"}/) { | 407 | if ($full_line =~ /$success_line/) { |
353 | $booted = 1; | 408 | $booted = 1; |
354 | } | 409 | } |
355 | 410 | ||
@@ -376,14 +431,14 @@ sub monitor { | |||
376 | 431 | ||
377 | close(DMESG); | 432 | close(DMESG); |
378 | 433 | ||
379 | if (!$booted) { | 434 | if ($bug) { |
380 | return 0 if ($in_bisect); | 435 | return 0 if ($in_bisect); |
381 | fail "failed - never got a boot prompt.\n" and return 0; | 436 | fail "failed - got a bug report\n" and return 0; |
382 | } | 437 | } |
383 | 438 | ||
384 | if ($bug) { | 439 | if (!$booted) { |
385 | return 0 if ($in_bisect); | 440 | return 0 if ($in_bisect); |
386 | fail "failed - got a bug report\n" and return 0; | 441 | fail "failed - never got a boot prompt.\n" and return 0; |
387 | } | 442 | } |
388 | 443 | ||
389 | return 1; | 444 | return 1; |
@@ -391,14 +446,14 @@ sub monitor { | |||
391 | 446 | ||
392 | sub install { | 447 | sub install { |
393 | 448 | ||
394 | run_command "scp $opt{OUTPUT_DIR}/$opt{BUILD_TARGET} $target:$opt{TARGET_IMAGE}" or | 449 | run_command "scp $outputdir/$build_target $target:$target_image" or |
395 | dodie "failed to copy image"; | 450 | dodie "failed to copy image"; |
396 | 451 | ||
397 | my $install_mods = 0; | 452 | my $install_mods = 0; |
398 | 453 | ||
399 | # should we process modules? | 454 | # should we process modules? |
400 | $install_mods = 0; | 455 | $install_mods = 0; |
401 | open(IN, "$opt{OUTPUT_DIR}/.config") or dodie("Can't read config file"); | 456 | open(IN, "$outputdir/.config") or dodie("Can't read config file"); |
402 | while (<IN>) { | 457 | while (<IN>) { |
403 | if (/CONFIG_MODULES(=y)?/) { | 458 | if (/CONFIG_MODULES(=y)?/) { |
404 | $install_mods = 1 if (defined($1)); | 459 | $install_mods = 1 if (defined($1)); |
@@ -412,7 +467,7 @@ sub install { | |||
412 | return; | 467 | return; |
413 | } | 468 | } |
414 | 469 | ||
415 | run_command "$make INSTALL_MOD_PATH=$opt{TMP_DIR} modules_install" or | 470 | run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or |
416 | dodie "Failed to install modules"; | 471 | dodie "Failed to install modules"; |
417 | 472 | ||
418 | my $modlib = "/lib/modules/$version"; | 473 | my $modlib = "/lib/modules/$version"; |
@@ -422,13 +477,13 @@ sub install { | |||
422 | dodie "failed to remove old mods: $modlib"; | 477 | dodie "failed to remove old mods: $modlib"; |
423 | 478 | ||
424 | # would be nice if scp -r did not follow symbolic links | 479 | # would be nice if scp -r did not follow symbolic links |
425 | run_command "cd $opt{TMP_DIR} && tar -cjf $modtar lib/modules/$version" or | 480 | run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or |
426 | dodie "making tarball"; | 481 | dodie "making tarball"; |
427 | 482 | ||
428 | run_command "scp $opt{TMP_DIR}/$modtar $target:/tmp" or | 483 | run_command "scp $tmpdir/$modtar $target:/tmp" or |
429 | dodie "failed to copy modules"; | 484 | dodie "failed to copy modules"; |
430 | 485 | ||
431 | unlink "$opt{TMP_DIR}/$modtar"; | 486 | unlink "$tmpdir/$modtar"; |
432 | 487 | ||
433 | run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or | 488 | run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or |
434 | dodie "failed to tar modules"; | 489 | dodie "failed to tar modules"; |
@@ -456,7 +511,7 @@ sub check_buildlog { | |||
456 | if (/^\s*(.*?):.*(warning|error)/) { | 511 | if (/^\s*(.*?):.*(warning|error)/) { |
457 | my $err = $1; | 512 | my $err = $1; |
458 | foreach my $file (@files) { | 513 | foreach my $file (@files) { |
459 | my $fullpath = "$opt{BUILD_DIR}/$file"; | 514 | my $fullpath = "$builddir/$file"; |
460 | if ($file eq $err || $fullpath eq $err) { | 515 | if ($file eq $err || $fullpath eq $err) { |
461 | fail "$file built with warnings" and return 0; | 516 | fail "$file built with warnings" and return 0; |
462 | } | 517 | } |
@@ -476,7 +531,7 @@ sub build { | |||
476 | unlink $buildlog; | 531 | unlink $buildlog; |
477 | 532 | ||
478 | if ($type =~ /^useconfig:(.*)/) { | 533 | if ($type =~ /^useconfig:(.*)/) { |
479 | run_command "cp $1 $opt{OUTPUT_DIR}/.config" or | 534 | run_command "cp $1 $outputdir/.config" or |
480 | dodie "could not copy $1 to .config"; | 535 | dodie "could not copy $1 to .config"; |
481 | 536 | ||
482 | $type = "oldconfig"; | 537 | $type = "oldconfig"; |
@@ -487,38 +542,38 @@ sub build { | |||
487 | $append = "yes ''|"; | 542 | $append = "yes ''|"; |
488 | 543 | ||
489 | # allow for empty configs | 544 | # allow for empty configs |
490 | run_command "touch $opt{OUTPUT_DIR}/.config"; | 545 | run_command "touch $outputdir/.config"; |
491 | 546 | ||
492 | run_command "mv $opt{OUTPUT_DIR}/.config $opt{OUTPUT_DIR}/config_temp" or | 547 | run_command "mv $outputdir/.config $outputdir/config_temp" or |
493 | dodie "moving .config"; | 548 | dodie "moving .config"; |
494 | 549 | ||
495 | if (!$noclean && !run_command "$make mrproper") { | 550 | if (!$noclean && !run_command "$make mrproper") { |
496 | dodie "make mrproper"; | 551 | dodie "make mrproper"; |
497 | } | 552 | } |
498 | 553 | ||
499 | run_command "mv $opt{OUTPUT_DIR}/config_temp $opt{OUTPUT_DIR}/.config" or | 554 | run_command "mv $outputdir/config_temp $outputdir/.config" or |
500 | dodie "moving config_temp"; | 555 | dodie "moving config_temp"; |
501 | 556 | ||
502 | } elsif (!$noclean) { | 557 | } elsif (!$noclean) { |
503 | unlink "$opt{OUTPUT_DIR}/.config"; | 558 | unlink "$outputdir/.config"; |
504 | run_command "$make mrproper" or | 559 | run_command "$make mrproper" or |
505 | dodie "make mrproper"; | 560 | dodie "make mrproper"; |
506 | } | 561 | } |
507 | 562 | ||
508 | # add something to distinguish this build | 563 | # add something to distinguish this build |
509 | open(OUT, "> $opt{OUTPUT_DIR}/localversion") or dodie("Can't make localversion file"); | 564 | open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); |
510 | print OUT "$opt{LOCALVERSION}\n"; | 565 | print OUT "$localversion\n"; |
511 | close(OUT); | 566 | close(OUT); |
512 | 567 | ||
513 | if (defined($minconfig)) { | 568 | if (defined($minconfig)) { |
514 | $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; | 569 | $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; |
515 | } | 570 | } |
516 | 571 | ||
517 | run_command "$defconfig $append $make $type" or | 572 | run_command "$append $defconfig $make $type" or |
518 | dodie "failed make config"; | 573 | dodie "failed make config"; |
519 | 574 | ||
520 | $redirect = "$opt{TMP_DIR}/buildlog"; | 575 | $redirect = "$buildlog"; |
521 | if (!run_command "$make $opt{BUILD_OPTIONS}") { | 576 | if (!run_command "$make $build_options") { |
522 | undef $redirect; | 577 | undef $redirect; |
523 | # bisect may need this to pass | 578 | # bisect may need this to pass |
524 | return 0 if ($in_bisect); | 579 | return 0 if ($in_bisect); |
@@ -530,9 +585,9 @@ sub build { | |||
530 | } | 585 | } |
531 | 586 | ||
532 | sub halt { | 587 | sub halt { |
533 | if (!run_command "ssh $target halt" or defined($opt{"POWER_OFF"})) { | 588 | if (!run_command "ssh $target halt" or defined($power_off)) { |
534 | # nope? the zap it! | 589 | # nope? the zap it! |
535 | run_command "$opt{POWER_OFF}"; | 590 | run_command "$power_off"; |
536 | } | 591 | } |
537 | } | 592 | } |
538 | 593 | ||
@@ -541,15 +596,17 @@ sub success { | |||
541 | 596 | ||
542 | doprint "\n\n*******************************************\n"; | 597 | doprint "\n\n*******************************************\n"; |
543 | doprint "*******************************************\n"; | 598 | doprint "*******************************************\n"; |
544 | doprint "** SUCCESS!!!! **\n"; | 599 | doprint "** TEST $i SUCCESS!!!! **\n"; |
545 | doprint "*******************************************\n"; | 600 | doprint "*******************************************\n"; |
546 | doprint "*******************************************\n"; | 601 | doprint "*******************************************\n"; |
547 | 602 | ||
548 | if ($i != $opt{"NUM_BUILDS"}) { | 603 | if ($i != $opt{"NUM_TESTS"} && $test_type ne "build" && |
549 | doprint "Reboot and wait $opt{SLEEP_TIME} seconds\n"; | 604 | !($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") && |
605 | !($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build")) { | ||
606 | doprint "Reboot and wait $sleep_time seconds\n"; | ||
550 | reboot; | 607 | reboot; |
551 | start_monitor; | 608 | start_monitor; |
552 | wait_for_monitor $opt{"SLEEP_TIME"}; | 609 | wait_for_monitor $sleep_time; |
553 | end_monitor; | 610 | end_monitor; |
554 | } | 611 | } |
555 | } | 612 | } |
@@ -566,9 +623,9 @@ sub child_run_test { | |||
566 | my $failed = 0; | 623 | my $failed = 0; |
567 | 624 | ||
568 | # child should have no power | 625 | # child should have no power |
569 | $opt{"REBOOT_ON_ERROR"} = 0; | 626 | $reboot_on_error = 0; |
570 | $opt{"POWEROFF_ON_ERROR"} = 0; | 627 | $poweroff_on_error = 0; |
571 | $opt{"DIE_ON_FAILURE"} = 1; | 628 | $die_on_failure = 1; |
572 | 629 | ||
573 | run_command $run_test or $failed = 1; | 630 | run_command $run_test or $failed = 1; |
574 | exit $failed; | 631 | exit $failed; |
@@ -638,6 +695,36 @@ sub do_run_test { | |||
638 | return 1; | 695 | return 1; |
639 | } | 696 | } |
640 | 697 | ||
698 | sub run_git_bisect { | ||
699 | my ($command) = @_; | ||
700 | |||
701 | doprint "$command ... "; | ||
702 | |||
703 | my $output = `$command 2>&1`; | ||
704 | my $ret = $?; | ||
705 | |||
706 | logit $output; | ||
707 | |||
708 | if ($ret) { | ||
709 | doprint "FAILED\n"; | ||
710 | dodie "Failed to git bisect"; | ||
711 | } | ||
712 | |||
713 | doprint "SUCCESS\n"; | ||
714 | if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { | ||
715 | doprint "$1 [$2]\n"; | ||
716 | } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { | ||
717 | $bisect_bad = $1; | ||
718 | doprint "Found bad commit... $1\n"; | ||
719 | return 0; | ||
720 | } else { | ||
721 | # we already logged it, just print it now. | ||
722 | print $output; | ||
723 | } | ||
724 | |||
725 | return 1; | ||
726 | } | ||
727 | |||
641 | sub run_bisect { | 728 | sub run_bisect { |
642 | my ($type) = @_; | 729 | my ($type) = @_; |
643 | 730 | ||
@@ -676,11 +763,11 @@ sub run_bisect { | |||
676 | $result = "bad"; | 763 | $result = "bad"; |
677 | 764 | ||
678 | # reboot the box to a good kernel | 765 | # reboot the box to a good kernel |
679 | if ($type eq "boot") { | 766 | if ($type ne "build") { |
680 | doprint "Reboot and sleep $opt{BISECT_SLEEP_TIME} seconds\n"; | 767 | doprint "Reboot and sleep $bisect_sleep_time seconds\n"; |
681 | reboot; | 768 | reboot; |
682 | start_monitor; | 769 | start_monitor; |
683 | wait_for_monitor $opt{"BISECT_SLEEP_TIME"}; | 770 | wait_for_monitor $bisect_sleep_time; |
684 | end_monitor; | 771 | end_monitor; |
685 | } | 772 | } |
686 | } else { | 773 | } else { |
@@ -696,31 +783,7 @@ sub run_bisect { | |||
696 | } | 783 | } |
697 | } | 784 | } |
698 | 785 | ||
699 | doprint "git bisect $result ... "; | 786 | return $result; |
700 | $output = `git bisect $result 2>&1`; | ||
701 | $ret = $?; | ||
702 | |||
703 | logit $output; | ||
704 | |||
705 | if ($ret) { | ||
706 | doprint "FAILED\n"; | ||
707 | fail "Failed to git bisect"; | ||
708 | } | ||
709 | |||
710 | doprint "SUCCESS\n"; | ||
711 | if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { | ||
712 | doprint "$1 [$2]\n"; | ||
713 | } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { | ||
714 | $bisect_bad = $1; | ||
715 | doprint "Found bad commit... $1\n"; | ||
716 | return 0; | ||
717 | } else { | ||
718 | # we already logged it, just print it now. | ||
719 | print $output; | ||
720 | } | ||
721 | |||
722 | |||
723 | return 1; | ||
724 | } | 787 | } |
725 | 788 | ||
726 | sub bisect { | 789 | sub bisect { |
@@ -735,6 +798,8 @@ sub bisect { | |||
735 | my $good = $opt{"BISECT_GOOD[$i]"}; | 798 | my $good = $opt{"BISECT_GOOD[$i]"}; |
736 | my $bad = $opt{"BISECT_BAD[$i]"}; | 799 | my $bad = $opt{"BISECT_BAD[$i]"}; |
737 | my $type = $opt{"BISECT_TYPE[$i]"}; | 800 | my $type = $opt{"BISECT_TYPE[$i]"}; |
801 | my $start = $opt{"BISECT_START[$i]"}; | ||
802 | my $replay = $opt{"BISECT_REPLAY[$i]"}; | ||
738 | 803 | ||
739 | if (defined($opt{"BISECT_REVERSE[$i]"}) && | 804 | if (defined($opt{"BISECT_REVERSE[$i]"}) && |
740 | $opt{"BISECT_REVERSE[$i]"} == 1) { | 805 | $opt{"BISECT_REVERSE[$i]"} == 1) { |
@@ -746,23 +811,83 @@ sub bisect { | |||
746 | 811 | ||
747 | $in_bisect = 1; | 812 | $in_bisect = 1; |
748 | 813 | ||
814 | # Can't have a test without having a test to run | ||
815 | if ($type eq "test" && !defined($run_test)) { | ||
816 | $type = "boot"; | ||
817 | } | ||
818 | |||
819 | my $check = $opt{"BISECT_CHECK[$i]"}; | ||
820 | if (defined($check) && $check ne "0") { | ||
821 | |||
822 | # get current HEAD | ||
823 | doprint "git rev-list HEAD --max-count=1 ... "; | ||
824 | my $head = `git rev-list HEAD --max-count=1`; | ||
825 | my $ret = $?; | ||
826 | |||
827 | logit $head; | ||
828 | |||
829 | if ($ret) { | ||
830 | doprint "FAILED\n"; | ||
831 | dodie "Failed to get git HEAD"; | ||
832 | } | ||
833 | |||
834 | print "SUCCESS\n"; | ||
835 | |||
836 | chomp $head; | ||
837 | |||
838 | if ($check ne "good") { | ||
839 | doprint "TESTING BISECT BAD [$bad]\n"; | ||
840 | run_command "git checkout $bad" or | ||
841 | die "Failed to checkout $bad"; | ||
842 | |||
843 | $result = run_bisect $type; | ||
844 | |||
845 | if ($result ne "bad") { | ||
846 | fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; | ||
847 | } | ||
848 | } | ||
849 | |||
850 | if ($check ne "bad") { | ||
851 | doprint "TESTING BISECT GOOD [$good]\n"; | ||
852 | run_command "git checkout $good" or | ||
853 | die "Failed to checkout $good"; | ||
854 | |||
855 | $result = run_bisect $type; | ||
856 | |||
857 | if ($result ne "good") { | ||
858 | fail "Tested BISECT_GOOD [$good] and it failed" and return 0; | ||
859 | } | ||
860 | } | ||
861 | |||
862 | # checkout where we started | ||
863 | run_command "git checkout $head" or | ||
864 | die "Failed to checkout $head"; | ||
865 | } | ||
866 | |||
749 | run_command "git bisect start" or | 867 | run_command "git bisect start" or |
750 | fail "could not start bisect"; | 868 | dodie "could not start bisect"; |
751 | 869 | ||
752 | run_command "git bisect good $good" or | 870 | run_command "git bisect good $good" or |
753 | fail "could not set bisect good to $good"; | 871 | dodie "could not set bisect good to $good"; |
754 | 872 | ||
755 | run_command "git bisect bad $bad" or | 873 | run_git_bisect "git bisect bad $bad" or |
756 | fail "could not set bisect good to $bad"; | 874 | dodie "could not set bisect bad to $bad"; |
757 | 875 | ||
758 | # Can't have a test without having a test to run | 876 | if (defined($replay)) { |
759 | if ($type eq "test" && !defined($run_test)) { | 877 | run_command "git bisect replay $replay" or |
760 | $type = "boot"; | 878 | dodie "failed to run replay"; |
761 | } | 879 | } |
762 | 880 | ||
881 | if (defined($start)) { | ||
882 | run_command "git checkout $start" or | ||
883 | dodie "failed to checkout $start"; | ||
884 | } | ||
885 | |||
886 | my $test; | ||
763 | do { | 887 | do { |
764 | $result = run_bisect $type; | 888 | $result = run_bisect $type; |
765 | } while ($result); | 889 | $test = run_git_bisect "git bisect $result"; |
890 | } while ($test); | ||
766 | 891 | ||
767 | run_command "git bisect log" or | 892 | run_command "git bisect log" or |
768 | dodie "could not capture git bisect log"; | 893 | dodie "could not capture git bisect log"; |
@@ -883,11 +1008,6 @@ die "TARGET_IMAGE not defined\n" if (!defined($opt{"TARGET_IMAGE"})); | |||
883 | die "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"})); | 1008 | die "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"})); |
884 | die "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"})); | 1009 | die "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"})); |
885 | die "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"})); | 1010 | die "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"})); |
886 | die "GRUB_MENU not defined\n" if (!defined($opt{"GRUB_MENU"})); | ||
887 | |||
888 | chdir $opt{"BUILD_DIR"} || die "can't change directory to $opt{BUILD_DIR}"; | ||
889 | |||
890 | $target = "$opt{SSH_USER}\@$opt{MACHINE}"; | ||
891 | 1011 | ||
892 | if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { | 1012 | if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { |
893 | unlink $opt{"LOG_FILE"}; | 1013 | unlink $opt{"LOG_FILE"}; |
@@ -899,11 +1019,7 @@ foreach my $option (sort keys %opt) { | |||
899 | doprint "$option = $opt{$option}\n"; | 1019 | doprint "$option = $opt{$option}\n"; |
900 | } | 1020 | } |
901 | 1021 | ||
902 | $buildlog = "$opt{TMP_DIR}/buildlog"; | 1022 | sub set_test_option { |
903 | $dmesg = "$opt{TMP_DIR}/dmesg"; | ||
904 | $make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}"; | ||
905 | |||
906 | sub set_build_option { | ||
907 | my ($name, $i) = @_; | 1023 | my ($name, $i) = @_; |
908 | 1024 | ||
909 | my $option = "$name\[$i\]"; | 1025 | my $option = "$name\[$i\]"; |
@@ -920,16 +1036,74 @@ sub set_build_option { | |||
920 | } | 1036 | } |
921 | 1037 | ||
922 | # First we need to do is the builds | 1038 | # First we need to do is the builds |
923 | for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { | 1039 | for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { |
1040 | |||
1041 | my $ssh_user = set_test_option("SSH_USER", $i); | ||
1042 | my $makecmd = set_test_option("MAKE_CMD", $i); | ||
1043 | |||
1044 | $machine = set_test_option("MACHINE", $i); | ||
1045 | $tmpdir = set_test_option("TMP_DIR", $i); | ||
1046 | $outputdir = set_test_option("OUTPUT_DIR", $i); | ||
1047 | $builddir = set_test_option("BUILD_DIR", $i); | ||
1048 | $test_type = set_test_option("TEST_TYPE", $i); | ||
1049 | $build_type = set_test_option("BUILD_TYPE", $i); | ||
1050 | $build_options = set_test_option("BUILD_OPTIONS", $i); | ||
1051 | $power_cycle = set_test_option("POWER_CYCLE", $i); | ||
1052 | $noclean = set_test_option("BUILD_NOCLEAN", $i); | ||
1053 | $minconfig = set_test_option("MIN_CONFIG", $i); | ||
1054 | $run_test = set_test_option("TEST", $i); | ||
1055 | $addconfig = set_test_option("ADD_CONFIG", $i); | ||
1056 | $reboot_type = set_test_option("REBOOT_TYPE", $i); | ||
1057 | $grub_menu = set_test_option("GRUB_MENU", $i); | ||
1058 | $reboot_script = set_test_option("REBOOT_SCRIPT", $i); | ||
1059 | $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); | ||
1060 | $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); | ||
1061 | $die_on_failure = set_test_option("DIE_ON_FAILURE", $i); | ||
1062 | $power_off = set_test_option("POWER_OFF", $i); | ||
1063 | $sleep_time = set_test_option("SLEEP_TIME", $i); | ||
1064 | $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); | ||
1065 | $store_failures = set_test_option("STORE_FAILURES", $i); | ||
1066 | $timeout = set_test_option("TIMEOUT", $i); | ||
1067 | $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); | ||
1068 | $console = set_test_option("CONSOLE", $i); | ||
1069 | $success_line = set_test_option("SUCCESS_LINE", $i); | ||
1070 | $build_target = set_test_option("BUILD_TARGET", $i); | ||
1071 | $target_image = set_test_option("TARGET_IMAGE", $i); | ||
1072 | $localversion = set_test_option("LOCALVERSION", $i); | ||
1073 | |||
1074 | chdir $builddir || die "can't change directory to $builddir"; | ||
1075 | |||
1076 | if (!-d $tmpdir) { | ||
1077 | mkpath($tmpdir) or | ||
1078 | die "can't create $tmpdir"; | ||
1079 | } | ||
924 | 1080 | ||
925 | $build_type = set_build_option("BUILD_TYPE", $i); | 1081 | $target = "$ssh_user\@$machine"; |
926 | $noclean = set_build_option("BUILD_NOCLEAN", $i); | 1082 | |
927 | $minconfig = set_build_option("MIN_CONFIG", $i); | 1083 | $buildlog = "$tmpdir/buildlog-$machine"; |
928 | $run_test = set_build_option("TEST", $i); | 1084 | $dmesg = "$tmpdir/dmesg-$machine"; |
929 | $addconfig = set_build_option("ADD_CONFIG", $i); | 1085 | $make = "$makecmd O=$outputdir"; |
1086 | |||
1087 | if ($reboot_type eq "grub") { | ||
1088 | dodie "GRUB_MENU not defined\n" if (!defined($grub_menu)); | ||
1089 | } elsif (!defined($reboot_script)) { | ||
1090 | dodie "REBOOT_SCRIPT not defined\n" | ||
1091 | } | ||
1092 | |||
1093 | my $run_type = $build_type; | ||
1094 | if ($test_type eq "patchcheck") { | ||
1095 | $run_type = $opt{"PATCHCHECK_TYPE[$i]"}; | ||
1096 | } elsif ($test_type eq "bisect") { | ||
1097 | $run_type = $opt{"BISECT_TYPE[$i]"}; | ||
1098 | } | ||
1099 | |||
1100 | # mistake in config file? | ||
1101 | if (!defined($run_type)) { | ||
1102 | $run_type = "ERROR"; | ||
1103 | } | ||
930 | 1104 | ||
931 | doprint "\n\n"; | 1105 | doprint "\n\n"; |
932 | doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $build_type\n\n"; | 1106 | doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n"; |
933 | 1107 | ||
934 | unlink $dmesg; | 1108 | unlink $dmesg; |
935 | unlink $buildlog; | 1109 | unlink $buildlog; |
@@ -938,9 +1112,9 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { | |||
938 | $minconfig = $addconfig; | 1112 | $minconfig = $addconfig; |
939 | 1113 | ||
940 | } elsif (defined($addconfig)) { | 1114 | } elsif (defined($addconfig)) { |
941 | run_command "cat $addconfig $minconfig > $opt{TMP_DIR}/use_config" or | 1115 | run_command "cat $addconfig $minconfig > $tmpdir/use_config" or |
942 | dodie "Failed to create temp config"; | 1116 | dodie "Failed to create temp config"; |
943 | $minconfig = "$opt{TMP_DIR}/use_config"; | 1117 | $minconfig = "$tmpdir/use_config"; |
944 | } | 1118 | } |
945 | 1119 | ||
946 | my $checkout = $opt{"CHECKOUT[$i]"}; | 1120 | my $checkout = $opt{"CHECKOUT[$i]"}; |
@@ -949,10 +1123,10 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { | |||
949 | die "failed to checkout $checkout"; | 1123 | die "failed to checkout $checkout"; |
950 | } | 1124 | } |
951 | 1125 | ||
952 | if ($build_type eq "bisect") { | 1126 | if ($test_type eq "bisect") { |
953 | bisect $i; | 1127 | bisect $i; |
954 | next; | 1128 | next; |
955 | } elsif ($build_type eq "patchcheck") { | 1129 | } elsif ($test_type eq "patchcheck") { |
956 | patchcheck $i; | 1130 | patchcheck $i; |
957 | next; | 1131 | next; |
958 | } | 1132 | } |
@@ -961,25 +1135,28 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { | |||
961 | build $build_type or next; | 1135 | build $build_type or next; |
962 | } | 1136 | } |
963 | 1137 | ||
964 | get_grub_index; | 1138 | if ($test_type ne "build") { |
965 | get_version; | 1139 | get_grub_index; |
966 | install; | 1140 | get_version; |
1141 | install; | ||
967 | 1142 | ||
968 | my $failed = 0; | 1143 | my $failed = 0; |
969 | start_monitor; | 1144 | start_monitor; |
970 | monitor or $failed = 1;; | 1145 | monitor or $failed = 1;; |
971 | if (!$failed && defined($run_test)) { | 1146 | |
972 | do_run_test or $failed = 1; | 1147 | if (!$failed && $test_type ne "boot" && defined($run_test)) { |
1148 | do_run_test or $failed = 1; | ||
1149 | } | ||
1150 | end_monitor; | ||
1151 | next if ($failed); | ||
973 | } | 1152 | } |
974 | end_monitor; | ||
975 | next if ($failed); | ||
976 | 1153 | ||
977 | success $i; | 1154 | success $i; |
978 | } | 1155 | } |
979 | 1156 | ||
980 | if ($opt{"POWEROFF_ON_SUCCESS"}) { | 1157 | if ($opt{"POWEROFF_ON_SUCCESS"}) { |
981 | halt; | 1158 | halt; |
982 | } elsif ($opt{"REBOOT_ON_SUCCESS"}) { | 1159 | } elsif ($opt{"REBOOT_ON_SUCCESS"} && $test_type ne "build") { |
983 | reboot; | 1160 | reboot; |
984 | } | 1161 | } |
985 | 1162 | ||