diff options
Diffstat (limited to 'tools/testing/ktest/ktest.pl')
-rwxr-xr-x | tools/testing/ktest/ktest.pl | 531 |
1 files changed, 426 insertions, 105 deletions
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 8d02ccb10c59..8b4c2535b266 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl | |||
@@ -42,6 +42,7 @@ $default{"BISECT_MANUAL"} = 0; | |||
42 | $default{"BISECT_SKIP"} = 1; | 42 | $default{"BISECT_SKIP"} = 1; |
43 | $default{"SUCCESS_LINE"} = "login:"; | 43 | $default{"SUCCESS_LINE"} = "login:"; |
44 | $default{"DETECT_TRIPLE_FAULT"} = 1; | 44 | $default{"DETECT_TRIPLE_FAULT"} = 1; |
45 | $default{"NO_INSTALL"} = 0; | ||
45 | $default{"BOOTED_TIMEOUT"} = 1; | 46 | $default{"BOOTED_TIMEOUT"} = 1; |
46 | $default{"DIE_ON_FAILURE"} = 1; | 47 | $default{"DIE_ON_FAILURE"} = 1; |
47 | $default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND"; | 48 | $default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND"; |
@@ -84,6 +85,7 @@ my $grub_number; | |||
84 | my $target; | 85 | my $target; |
85 | my $make; | 86 | my $make; |
86 | my $post_install; | 87 | my $post_install; |
88 | my $no_install; | ||
87 | my $noclean; | 89 | my $noclean; |
88 | my $minconfig; | 90 | my $minconfig; |
89 | my $start_minconfig; | 91 | my $start_minconfig; |
@@ -115,6 +117,7 @@ my $timeout; | |||
115 | my $booted_timeout; | 117 | my $booted_timeout; |
116 | my $detect_triplefault; | 118 | my $detect_triplefault; |
117 | my $console; | 119 | my $console; |
120 | my $reboot_success_line; | ||
118 | my $success_line; | 121 | my $success_line; |
119 | my $stop_after_success; | 122 | my $stop_after_success; |
120 | my $stop_after_failure; | 123 | my $stop_after_failure; |
@@ -130,6 +133,12 @@ my %config_help; | |||
130 | my %variable; | 133 | my %variable; |
131 | my %force_config; | 134 | my %force_config; |
132 | 135 | ||
136 | # do not force reboots on config problems | ||
137 | my $no_reboot = 1; | ||
138 | |||
139 | # default variables that can be used | ||
140 | chomp ($variable{"PWD"} = `pwd`); | ||
141 | |||
133 | $config_help{"MACHINE"} = << "EOF" | 142 | $config_help{"MACHINE"} = << "EOF" |
134 | The machine hostname that you will test. | 143 | The machine hostname that you will test. |
135 | EOF | 144 | EOF |
@@ -241,6 +250,7 @@ sub read_yn { | |||
241 | 250 | ||
242 | sub get_ktest_config { | 251 | sub get_ktest_config { |
243 | my ($config) = @_; | 252 | my ($config) = @_; |
253 | my $ans; | ||
244 | 254 | ||
245 | return if (defined($opt{$config})); | 255 | return if (defined($opt{$config})); |
246 | 256 | ||
@@ -254,16 +264,17 @@ sub get_ktest_config { | |||
254 | if (defined($default{$config})) { | 264 | if (defined($default{$config})) { |
255 | print "\[$default{$config}\] "; | 265 | print "\[$default{$config}\] "; |
256 | } | 266 | } |
257 | $entered_configs{$config} = <STDIN>; | 267 | $ans = <STDIN>; |
258 | $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/; | 268 | $ans =~ s/^\s*(.*\S)\s*$/$1/; |
259 | if ($entered_configs{$config} =~ /^\s*$/) { | 269 | if ($ans =~ /^\s*$/) { |
260 | if ($default{$config}) { | 270 | if ($default{$config}) { |
261 | $entered_configs{$config} = $default{$config}; | 271 | $ans = $default{$config}; |
262 | } else { | 272 | } else { |
263 | print "Your answer can not be blank\n"; | 273 | print "Your answer can not be blank\n"; |
264 | next; | 274 | next; |
265 | } | 275 | } |
266 | } | 276 | } |
277 | $entered_configs{$config} = process_variables($ans); | ||
267 | last; | 278 | last; |
268 | } | 279 | } |
269 | } | 280 | } |
@@ -298,7 +309,7 @@ sub get_ktest_configs { | |||
298 | } | 309 | } |
299 | 310 | ||
300 | sub process_variables { | 311 | sub process_variables { |
301 | my ($value) = @_; | 312 | my ($value, $remove_undef) = @_; |
302 | my $retval = ""; | 313 | my $retval = ""; |
303 | 314 | ||
304 | # We want to check for '\', and it is just easier | 315 | # We want to check for '\', and it is just easier |
@@ -316,6 +327,10 @@ sub process_variables { | |||
316 | $retval = "$retval$begin"; | 327 | $retval = "$retval$begin"; |
317 | if (defined($variable{$var})) { | 328 | if (defined($variable{$var})) { |
318 | $retval = "$retval$variable{$var}"; | 329 | $retval = "$retval$variable{$var}"; |
330 | } elsif (defined($remove_undef) && $remove_undef) { | ||
331 | # for if statements, any variable that is not defined, | ||
332 | # we simple convert to 0 | ||
333 | $retval = "${retval}0"; | ||
319 | } else { | 334 | } else { |
320 | # put back the origin piece. | 335 | # put back the origin piece. |
321 | $retval = "$retval\$\{$var\}"; | 336 | $retval = "$retval\$\{$var\}"; |
@@ -331,10 +346,17 @@ sub process_variables { | |||
331 | } | 346 | } |
332 | 347 | ||
333 | sub set_value { | 348 | sub set_value { |
334 | my ($lvalue, $rvalue) = @_; | 349 | my ($lvalue, $rvalue, $override, $overrides, $name) = @_; |
335 | 350 | ||
336 | if (defined($opt{$lvalue})) { | 351 | if (defined($opt{$lvalue})) { |
337 | die "Error: Option $lvalue defined more than once!\n"; | 352 | if (!$override || defined(${$overrides}{$lvalue})) { |
353 | my $extra = ""; | ||
354 | if ($override) { | ||
355 | $extra = "In the same override section!\n"; | ||
356 | } | ||
357 | die "$name: $.: Option $lvalue defined more than once!\n$extra"; | ||
358 | } | ||
359 | ${$overrides}{$lvalue} = $rvalue; | ||
338 | } | 360 | } |
339 | if ($rvalue =~ /^\s*$/) { | 361 | if ($rvalue =~ /^\s*$/) { |
340 | delete $opt{$lvalue}; | 362 | delete $opt{$lvalue}; |
@@ -355,86 +377,274 @@ sub set_variable { | |||
355 | } | 377 | } |
356 | } | 378 | } |
357 | 379 | ||
358 | sub read_config { | 380 | sub process_compare { |
359 | my ($config) = @_; | 381 | my ($lval, $cmp, $rval) = @_; |
382 | |||
383 | # remove whitespace | ||
384 | |||
385 | $lval =~ s/^\s*//; | ||
386 | $lval =~ s/\s*$//; | ||
387 | |||
388 | $rval =~ s/^\s*//; | ||
389 | $rval =~ s/\s*$//; | ||
390 | |||
391 | if ($cmp eq "==") { | ||
392 | return $lval eq $rval; | ||
393 | } elsif ($cmp eq "!=") { | ||
394 | return $lval ne $rval; | ||
395 | } | ||
396 | |||
397 | my $statement = "$lval $cmp $rval"; | ||
398 | my $ret = eval $statement; | ||
399 | |||
400 | # $@ stores error of eval | ||
401 | if ($@) { | ||
402 | return -1; | ||
403 | } | ||
404 | |||
405 | return $ret; | ||
406 | } | ||
407 | |||
408 | sub value_defined { | ||
409 | my ($val) = @_; | ||
410 | |||
411 | return defined($variable{$2}) || | ||
412 | defined($opt{$2}); | ||
413 | } | ||
414 | |||
415 | my $d = 0; | ||
416 | sub process_expression { | ||
417 | my ($name, $val) = @_; | ||
418 | |||
419 | my $c = $d++; | ||
420 | |||
421 | while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) { | ||
422 | my $express = $1; | ||
423 | |||
424 | if (process_expression($name, $express)) { | ||
425 | $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /; | ||
426 | } else { | ||
427 | $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /; | ||
428 | } | ||
429 | } | ||
430 | |||
431 | $d--; | ||
432 | my $OR = "\\|\\|"; | ||
433 | my $AND = "\\&\\&"; | ||
434 | |||
435 | while ($val =~ s/^(.*?)($OR|$AND)//) { | ||
436 | my $express = $1; | ||
437 | my $op = $2; | ||
438 | |||
439 | if (process_expression($name, $express)) { | ||
440 | if ($op eq "||") { | ||
441 | return 1; | ||
442 | } | ||
443 | } else { | ||
444 | if ($op eq "&&") { | ||
445 | return 0; | ||
446 | } | ||
447 | } | ||
448 | } | ||
449 | |||
450 | if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) { | ||
451 | my $ret = process_compare($1, $2, $3); | ||
452 | if ($ret < 0) { | ||
453 | die "$name: $.: Unable to process comparison\n"; | ||
454 | } | ||
455 | return $ret; | ||
456 | } | ||
457 | |||
458 | if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) { | ||
459 | if (defined $1) { | ||
460 | return !value_defined($2); | ||
461 | } else { | ||
462 | return value_defined($2); | ||
463 | } | ||
464 | } | ||
465 | |||
466 | if ($val =~ /^\s*0\s*$/) { | ||
467 | return 0; | ||
468 | } elsif ($val =~ /^\s*\d+\s*$/) { | ||
469 | return 1; | ||
470 | } | ||
471 | |||
472 | die ("$name: $.: Undefined content $val in if statement\n"); | ||
473 | } | ||
474 | |||
475 | sub process_if { | ||
476 | my ($name, $value) = @_; | ||
360 | 477 | ||
361 | open(IN, $config) || die "can't read file $config"; | 478 | # Convert variables and replace undefined ones with 0 |
479 | my $val = process_variables($value, 1); | ||
480 | my $ret = process_expression $name, $val; | ||
481 | |||
482 | return $ret; | ||
483 | } | ||
484 | |||
485 | sub __read_config { | ||
486 | my ($config, $current_test_num) = @_; | ||
487 | |||
488 | my $in; | ||
489 | open($in, $config) || die "can't read file $config"; | ||
362 | 490 | ||
363 | my $name = $config; | 491 | my $name = $config; |
364 | $name =~ s,.*/(.*),$1,; | 492 | $name =~ s,.*/(.*),$1,; |
365 | 493 | ||
366 | my $test_num = 0; | 494 | my $test_num = $$current_test_num; |
367 | my $default = 1; | 495 | my $default = 1; |
368 | my $repeat = 1; | 496 | my $repeat = 1; |
369 | my $num_tests_set = 0; | 497 | my $num_tests_set = 0; |
370 | my $skip = 0; | 498 | my $skip = 0; |
371 | my $rest; | 499 | my $rest; |
500 | my $line; | ||
372 | my $test_case = 0; | 501 | my $test_case = 0; |
502 | my $if = 0; | ||
503 | my $if_set = 0; | ||
504 | my $override = 0; | ||
373 | 505 | ||
374 | while (<IN>) { | 506 | my %overrides; |
507 | |||
508 | while (<$in>) { | ||
375 | 509 | ||
376 | # ignore blank lines and comments | 510 | # ignore blank lines and comments |
377 | next if (/^\s*$/ || /\s*\#/); | 511 | next if (/^\s*$/ || /\s*\#/); |
378 | 512 | ||
379 | if (/^\s*TEST_START(.*)/) { | 513 | if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) { |
380 | 514 | ||
381 | $rest = $1; | 515 | my $type = $1; |
516 | $rest = $2; | ||
517 | $line = $2; | ||
382 | 518 | ||
383 | if ($num_tests_set) { | 519 | my $old_test_num; |
384 | die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; | 520 | my $old_repeat; |
385 | } | 521 | $override = 0; |
522 | |||
523 | if ($type eq "TEST_START") { | ||
386 | 524 | ||
387 | my $old_test_num = $test_num; | 525 | if ($num_tests_set) { |
388 | my $old_repeat = $repeat; | 526 | die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; |
527 | } | ||
389 | 528 | ||
390 | $test_num += $repeat; | 529 | $old_test_num = $test_num; |
391 | $default = 0; | 530 | $old_repeat = $repeat; |
392 | $repeat = 1; | ||
393 | 531 | ||
394 | if ($rest =~ /\s+SKIP(.*)/) { | 532 | $test_num += $repeat; |
395 | $rest = $1; | 533 | $default = 0; |
534 | $repeat = 1; | ||
535 | } else { | ||
536 | $default = 1; | ||
537 | } | ||
538 | |||
539 | # If SKIP is anywhere in the line, the command will be skipped | ||
540 | if ($rest =~ s/\s+SKIP\b//) { | ||
396 | $skip = 1; | 541 | $skip = 1; |
397 | } else { | 542 | } else { |
398 | $test_case = 1; | 543 | $test_case = 1; |
399 | $skip = 0; | 544 | $skip = 0; |
400 | } | 545 | } |
401 | 546 | ||
402 | if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) { | 547 | if ($rest =~ s/\sELSE\b//) { |
403 | $repeat = $1; | 548 | if (!$if) { |
404 | $rest = $2; | 549 | die "$name: $.: ELSE found with out matching IF section\n$_"; |
405 | $repeat_tests{"$test_num"} = $repeat; | 550 | } |
551 | $if = 0; | ||
552 | |||
553 | if ($if_set) { | ||
554 | $skip = 1; | ||
555 | } else { | ||
556 | $skip = 0; | ||
557 | } | ||
406 | } | 558 | } |
407 | 559 | ||
408 | if ($rest =~ /\s+SKIP(.*)/) { | 560 | if ($rest =~ s/\sIF\s+(.*)//) { |
409 | $rest = $1; | 561 | if (process_if($name, $1)) { |
410 | $skip = 1; | 562 | $if_set = 1; |
563 | } else { | ||
564 | $skip = 1; | ||
565 | } | ||
566 | $if = 1; | ||
567 | } else { | ||
568 | $if = 0; | ||
569 | $if_set = 0; | ||
411 | } | 570 | } |
412 | 571 | ||
413 | if ($rest !~ /^\s*$/) { | 572 | if (!$skip) { |
414 | die "$name: $.: Gargbage found after TEST_START\n$_"; | 573 | if ($type eq "TEST_START") { |
574 | if ($rest =~ s/\s+ITERATE\s+(\d+)//) { | ||
575 | $repeat = $1; | ||
576 | $repeat_tests{"$test_num"} = $repeat; | ||
577 | } | ||
578 | } elsif ($rest =~ s/\sOVERRIDE\b//) { | ||
579 | # DEFAULT only | ||
580 | $override = 1; | ||
581 | # Clear previous overrides | ||
582 | %overrides = (); | ||
583 | } | ||
584 | } | ||
585 | |||
586 | if (!$skip && $rest !~ /^\s*$/) { | ||
587 | die "$name: $.: Gargbage found after $type\n$_"; | ||
415 | } | 588 | } |
416 | 589 | ||
417 | if ($skip) { | 590 | if ($skip && $type eq "TEST_START") { |
418 | $test_num = $old_test_num; | 591 | $test_num = $old_test_num; |
419 | $repeat = $old_repeat; | 592 | $repeat = $old_repeat; |
420 | } | 593 | } |
421 | 594 | ||
422 | } elsif (/^\s*DEFAULTS(.*)$/) { | 595 | } elsif (/^\s*ELSE\b(.*)$/) { |
423 | $default = 1; | 596 | if (!$if) { |
424 | 597 | die "$name: $.: ELSE found with out matching IF section\n$_"; | |
598 | } | ||
425 | $rest = $1; | 599 | $rest = $1; |
426 | 600 | if ($if_set) { | |
427 | if ($rest =~ /\s+SKIP(.*)/) { | ||
428 | $rest = $1; | ||
429 | $skip = 1; | 601 | $skip = 1; |
602 | $rest = ""; | ||
430 | } else { | 603 | } else { |
431 | $skip = 0; | 604 | $skip = 0; |
605 | |||
606 | if ($rest =~ /\sIF\s+(.*)/) { | ||
607 | # May be a ELSE IF section. | ||
608 | if (!process_if($name, $1)) { | ||
609 | $skip = 1; | ||
610 | } | ||
611 | $rest = ""; | ||
612 | } else { | ||
613 | $if = 0; | ||
614 | } | ||
432 | } | 615 | } |
433 | 616 | ||
434 | if ($rest !~ /^\s*$/) { | 617 | if ($rest !~ /^\s*$/) { |
435 | die "$name: $.: Gargbage found after DEFAULTS\n$_"; | 618 | die "$name: $.: Gargbage found after DEFAULTS\n$_"; |
436 | } | 619 | } |
437 | 620 | ||
621 | } elsif (/^\s*INCLUDE\s+(\S+)/) { | ||
622 | |||
623 | next if ($skip); | ||
624 | |||
625 | if (!$default) { | ||
626 | die "$name: $.: INCLUDE can only be done in default sections\n$_"; | ||
627 | } | ||
628 | |||
629 | my $file = process_variables($1); | ||
630 | |||
631 | if ($file !~ m,^/,) { | ||
632 | # check the path of the config file first | ||
633 | if ($config =~ m,(.*)/,) { | ||
634 | if (-f "$1/$file") { | ||
635 | $file = "$1/$file"; | ||
636 | } | ||
637 | } | ||
638 | } | ||
639 | |||
640 | if ( ! -r $file ) { | ||
641 | die "$name: $.: Can't read file $file\n$_"; | ||
642 | } | ||
643 | |||
644 | if (__read_config($file, \$test_num)) { | ||
645 | $test_case = 1; | ||
646 | } | ||
647 | |||
438 | } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { | 648 | } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { |
439 | 649 | ||
440 | next if ($skip); | 650 | next if ($skip); |
@@ -460,10 +670,10 @@ sub read_config { | |||
460 | } | 670 | } |
461 | 671 | ||
462 | if ($default || $lvalue =~ /\[\d+\]$/) { | 672 | if ($default || $lvalue =~ /\[\d+\]$/) { |
463 | set_value($lvalue, $rvalue); | 673 | set_value($lvalue, $rvalue, $override, \%overrides, $name); |
464 | } else { | 674 | } else { |
465 | my $val = "$lvalue\[$test_num\]"; | 675 | my $val = "$lvalue\[$test_num\]"; |
466 | set_value($val, $rvalue); | 676 | set_value($val, $rvalue, $override, \%overrides, $name); |
467 | 677 | ||
468 | if ($repeat > 1) { | 678 | if ($repeat > 1) { |
469 | $repeats{$val} = $repeat; | 679 | $repeats{$val} = $repeat; |
@@ -490,13 +700,26 @@ sub read_config { | |||
490 | } | 700 | } |
491 | } | 701 | } |
492 | 702 | ||
493 | close(IN); | ||
494 | |||
495 | if ($test_num) { | 703 | if ($test_num) { |
496 | $test_num += $repeat - 1; | 704 | $test_num += $repeat - 1; |
497 | $opt{"NUM_TESTS"} = $test_num; | 705 | $opt{"NUM_TESTS"} = $test_num; |
498 | } | 706 | } |
499 | 707 | ||
708 | close($in); | ||
709 | |||
710 | $$current_test_num = $test_num; | ||
711 | |||
712 | return $test_case; | ||
713 | } | ||
714 | |||
715 | sub read_config { | ||
716 | my ($config) = @_; | ||
717 | |||
718 | my $test_case; | ||
719 | my $test_num = 0; | ||
720 | |||
721 | $test_case = __read_config $config, \$test_num; | ||
722 | |||
500 | # make sure we have all mandatory configs | 723 | # make sure we have all mandatory configs |
501 | get_ktest_configs; | 724 | get_ktest_configs; |
502 | 725 | ||
@@ -524,6 +747,18 @@ sub __eval_option { | |||
524 | # Add space to evaluate the character before $ | 747 | # Add space to evaluate the character before $ |
525 | $option = " $option"; | 748 | $option = " $option"; |
526 | my $retval = ""; | 749 | my $retval = ""; |
750 | my $repeated = 0; | ||
751 | my $parent = 0; | ||
752 | |||
753 | foreach my $test (keys %repeat_tests) { | ||
754 | if ($i >= $test && | ||
755 | $i < $test + $repeat_tests{$test}) { | ||
756 | |||
757 | $repeated = 1; | ||
758 | $parent = $test; | ||
759 | last; | ||
760 | } | ||
761 | } | ||
527 | 762 | ||
528 | while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { | 763 | while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { |
529 | my $start = $1; | 764 | my $start = $1; |
@@ -537,10 +772,14 @@ sub __eval_option { | |||
537 | # otherwise see if the default OPT (without [$i]) exists. | 772 | # otherwise see if the default OPT (without [$i]) exists. |
538 | 773 | ||
539 | my $o = "$var\[$i\]"; | 774 | my $o = "$var\[$i\]"; |
775 | my $parento = "$var\[$parent\]"; | ||
540 | 776 | ||
541 | if (defined($opt{$o})) { | 777 | if (defined($opt{$o})) { |
542 | $o = $opt{$o}; | 778 | $o = $opt{$o}; |
543 | $retval = "$retval$o"; | 779 | $retval = "$retval$o"; |
780 | } elsif ($repeated && defined($opt{$parento})) { | ||
781 | $o = $opt{$parento}; | ||
782 | $retval = "$retval$o"; | ||
544 | } elsif (defined($opt{$var})) { | 783 | } elsif (defined($opt{$var})) { |
545 | $o = $opt{$var}; | 784 | $o = $opt{$var}; |
546 | $retval = "$retval$o"; | 785 | $retval = "$retval$o"; |
@@ -603,8 +842,20 @@ sub doprint { | |||
603 | } | 842 | } |
604 | 843 | ||
605 | sub run_command; | 844 | sub run_command; |
845 | sub start_monitor; | ||
846 | sub end_monitor; | ||
847 | sub wait_for_monitor; | ||
606 | 848 | ||
607 | sub reboot { | 849 | sub reboot { |
850 | my ($time) = @_; | ||
851 | |||
852 | if (defined($time)) { | ||
853 | start_monitor; | ||
854 | # flush out current monitor | ||
855 | # May contain the reboot success line | ||
856 | wait_for_monitor 1; | ||
857 | } | ||
858 | |||
608 | # try to reboot normally | 859 | # try to reboot normally |
609 | if (run_command $reboot) { | 860 | if (run_command $reboot) { |
610 | if (defined($powercycle_after_reboot)) { | 861 | if (defined($powercycle_after_reboot)) { |
@@ -615,12 +866,17 @@ sub reboot { | |||
615 | # nope? power cycle it. | 866 | # nope? power cycle it. |
616 | run_command "$power_cycle"; | 867 | run_command "$power_cycle"; |
617 | } | 868 | } |
869 | |||
870 | if (defined($time)) { | ||
871 | wait_for_monitor($time, $reboot_success_line); | ||
872 | end_monitor; | ||
873 | } | ||
618 | } | 874 | } |
619 | 875 | ||
620 | sub do_not_reboot { | 876 | sub do_not_reboot { |
621 | my $i = $iteration; | 877 | my $i = $iteration; |
622 | 878 | ||
623 | return $test_type eq "build" || | 879 | return $test_type eq "build" || $no_reboot || |
624 | ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || | 880 | ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || |
625 | ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); | 881 | ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); |
626 | } | 882 | } |
@@ -693,16 +949,29 @@ sub end_monitor { | |||
693 | } | 949 | } |
694 | 950 | ||
695 | sub wait_for_monitor { | 951 | sub wait_for_monitor { |
696 | my ($time) = @_; | 952 | my ($time, $stop) = @_; |
953 | my $full_line = ""; | ||
697 | my $line; | 954 | my $line; |
955 | my $booted = 0; | ||
698 | 956 | ||
699 | doprint "** Wait for monitor to settle down **\n"; | 957 | doprint "** Wait for monitor to settle down **\n"; |
700 | 958 | ||
701 | # read the monitor and wait for the system to calm down | 959 | # read the monitor and wait for the system to calm down |
702 | do { | 960 | while (!$booted) { |
703 | $line = wait_for_input($monitor_fp, $time); | 961 | $line = wait_for_input($monitor_fp, $time); |
704 | print "$line" if (defined($line)); | 962 | last if (!defined($line)); |
705 | } while (defined($line)); | 963 | print "$line"; |
964 | $full_line .= $line; | ||
965 | |||
966 | if (defined($stop) && $full_line =~ /$stop/) { | ||
967 | doprint "wait for monitor detected $stop\n"; | ||
968 | $booted = 1; | ||
969 | } | ||
970 | |||
971 | if ($line =~ /\n/) { | ||
972 | $full_line = ""; | ||
973 | } | ||
974 | } | ||
706 | print "** Monitor flushed **\n"; | 975 | print "** Monitor flushed **\n"; |
707 | } | 976 | } |
708 | 977 | ||
@@ -719,10 +988,7 @@ sub fail { | |||
719 | # no need to reboot for just building. | 988 | # no need to reboot for just building. |
720 | if (!do_not_reboot) { | 989 | if (!do_not_reboot) { |
721 | doprint "REBOOTING\n"; | 990 | doprint "REBOOTING\n"; |
722 | reboot; | 991 | reboot $sleep_time; |
723 | start_monitor; | ||
724 | wait_for_monitor $sleep_time; | ||
725 | end_monitor; | ||
726 | } | 992 | } |
727 | 993 | ||
728 | my $name = ""; | 994 | my $name = ""; |
@@ -854,9 +1120,12 @@ sub get_grub_index { | |||
854 | open(IN, "$ssh_grub |") | 1120 | open(IN, "$ssh_grub |") |
855 | or die "unable to get menu.lst"; | 1121 | or die "unable to get menu.lst"; |
856 | 1122 | ||
1123 | my $found = 0; | ||
1124 | |||
857 | while (<IN>) { | 1125 | while (<IN>) { |
858 | if (/^\s*title\s+$grub_menu\s*$/) { | 1126 | if (/^\s*title\s+$grub_menu\s*$/) { |
859 | $grub_number++; | 1127 | $grub_number++; |
1128 | $found = 1; | ||
860 | last; | 1129 | last; |
861 | } elsif (/^\s*title\s/) { | 1130 | } elsif (/^\s*title\s/) { |
862 | $grub_number++; | 1131 | $grub_number++; |
@@ -865,7 +1134,7 @@ sub get_grub_index { | |||
865 | close(IN); | 1134 | close(IN); |
866 | 1135 | ||
867 | die "Could not find '$grub_menu' in /boot/grub/menu on $machine" | 1136 | die "Could not find '$grub_menu' in /boot/grub/menu on $machine" |
868 | if ($grub_number < 0); | 1137 | if (!$found); |
869 | doprint "$grub_number\n"; | 1138 | doprint "$grub_number\n"; |
870 | } | 1139 | } |
871 | 1140 | ||
@@ -902,7 +1171,8 @@ sub wait_for_input | |||
902 | 1171 | ||
903 | sub reboot_to { | 1172 | sub reboot_to { |
904 | if ($reboot_type eq "grub") { | 1173 | if ($reboot_type eq "grub") { |
905 | run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'"; | 1174 | run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'"; |
1175 | reboot; | ||
906 | return; | 1176 | return; |
907 | } | 1177 | } |
908 | 1178 | ||
@@ -1083,6 +1353,8 @@ sub do_post_install { | |||
1083 | 1353 | ||
1084 | sub install { | 1354 | sub install { |
1085 | 1355 | ||
1356 | return if ($no_install); | ||
1357 | |||
1086 | run_scp "$outputdir/$build_target", "$target_image" or | 1358 | run_scp "$outputdir/$build_target", "$target_image" or |
1087 | dodie "failed to copy image"; | 1359 | dodie "failed to copy image"; |
1088 | 1360 | ||
@@ -1140,6 +1412,11 @@ sub get_version { | |||
1140 | } | 1412 | } |
1141 | 1413 | ||
1142 | sub start_monitor_and_boot { | 1414 | sub start_monitor_and_boot { |
1415 | # Make sure the stable kernel has finished booting | ||
1416 | start_monitor; | ||
1417 | wait_for_monitor 5; | ||
1418 | end_monitor; | ||
1419 | |||
1143 | get_grub_index; | 1420 | get_grub_index; |
1144 | get_version; | 1421 | get_version; |
1145 | install; | 1422 | install; |
@@ -1250,6 +1527,10 @@ sub build { | |||
1250 | 1527 | ||
1251 | unlink $buildlog; | 1528 | unlink $buildlog; |
1252 | 1529 | ||
1530 | # Failed builds should not reboot the target | ||
1531 | my $save_no_reboot = $no_reboot; | ||
1532 | $no_reboot = 1; | ||
1533 | |||
1253 | if (defined($pre_build)) { | 1534 | if (defined($pre_build)) { |
1254 | my $ret = run_command $pre_build; | 1535 | my $ret = run_command $pre_build; |
1255 | if (!$ret && defined($pre_build_die) && | 1536 | if (!$ret && defined($pre_build_die) && |
@@ -1272,15 +1553,15 @@ sub build { | |||
1272 | # allow for empty configs | 1553 | # allow for empty configs |
1273 | run_command "touch $output_config"; | 1554 | run_command "touch $output_config"; |
1274 | 1555 | ||
1275 | run_command "mv $output_config $outputdir/config_temp" or | 1556 | if (!$noclean) { |
1276 | dodie "moving .config"; | 1557 | run_command "mv $output_config $outputdir/config_temp" or |
1558 | dodie "moving .config"; | ||
1277 | 1559 | ||
1278 | if (!$noclean && !run_command "$make mrproper") { | 1560 | run_command "$make mrproper" or dodie "make mrproper"; |
1279 | dodie "make mrproper"; | ||
1280 | } | ||
1281 | 1561 | ||
1282 | run_command "mv $outputdir/config_temp $output_config" or | 1562 | run_command "mv $outputdir/config_temp $output_config" or |
1283 | dodie "moving config_temp"; | 1563 | dodie "moving config_temp"; |
1564 | } | ||
1284 | 1565 | ||
1285 | } elsif (!$noclean) { | 1566 | } elsif (!$noclean) { |
1286 | unlink "$output_config"; | 1567 | unlink "$output_config"; |
@@ -1318,10 +1599,15 @@ sub build { | |||
1318 | 1599 | ||
1319 | if (!$build_ret) { | 1600 | if (!$build_ret) { |
1320 | # bisect may need this to pass | 1601 | # bisect may need this to pass |
1321 | return 0 if ($in_bisect); | 1602 | if ($in_bisect) { |
1603 | $no_reboot = $save_no_reboot; | ||
1604 | return 0; | ||
1605 | } | ||
1322 | fail "failed build" and return 0; | 1606 | fail "failed build" and return 0; |
1323 | } | 1607 | } |
1324 | 1608 | ||
1609 | $no_reboot = $save_no_reboot; | ||
1610 | |||
1325 | return 1; | 1611 | return 1; |
1326 | } | 1612 | } |
1327 | 1613 | ||
@@ -1356,10 +1642,7 @@ sub success { | |||
1356 | 1642 | ||
1357 | if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { | 1643 | if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { |
1358 | doprint "Reboot and wait $sleep_time seconds\n"; | 1644 | doprint "Reboot and wait $sleep_time seconds\n"; |
1359 | reboot; | 1645 | reboot $sleep_time; |
1360 | start_monitor; | ||
1361 | wait_for_monitor $sleep_time; | ||
1362 | end_monitor; | ||
1363 | } | 1646 | } |
1364 | } | 1647 | } |
1365 | 1648 | ||
@@ -1500,10 +1783,7 @@ sub run_git_bisect { | |||
1500 | 1783 | ||
1501 | sub bisect_reboot { | 1784 | sub bisect_reboot { |
1502 | doprint "Reboot and sleep $bisect_sleep_time seconds\n"; | 1785 | doprint "Reboot and sleep $bisect_sleep_time seconds\n"; |
1503 | reboot; | 1786 | reboot $bisect_sleep_time; |
1504 | start_monitor; | ||
1505 | wait_for_monitor $bisect_sleep_time; | ||
1506 | end_monitor; | ||
1507 | } | 1787 | } |
1508 | 1788 | ||
1509 | # returns 1 on success, 0 on failure, -1 on skip | 1789 | # returns 1 on success, 0 on failure, -1 on skip |
@@ -2066,10 +2346,7 @@ sub config_bisect { | |||
2066 | 2346 | ||
2067 | sub patchcheck_reboot { | 2347 | sub patchcheck_reboot { |
2068 | doprint "Reboot and sleep $patchcheck_sleep_time seconds\n"; | 2348 | doprint "Reboot and sleep $patchcheck_sleep_time seconds\n"; |
2069 | reboot; | 2349 | reboot $patchcheck_sleep_time; |
2070 | start_monitor; | ||
2071 | wait_for_monitor $patchcheck_sleep_time; | ||
2072 | end_monitor; | ||
2073 | } | 2350 | } |
2074 | 2351 | ||
2075 | sub patchcheck { | 2352 | sub patchcheck { |
@@ -2178,12 +2455,31 @@ sub patchcheck { | |||
2178 | } | 2455 | } |
2179 | 2456 | ||
2180 | my %depends; | 2457 | my %depends; |
2458 | my %depcount; | ||
2181 | my $iflevel = 0; | 2459 | my $iflevel = 0; |
2182 | my @ifdeps; | 2460 | my @ifdeps; |
2183 | 2461 | ||
2184 | # prevent recursion | 2462 | # prevent recursion |
2185 | my %read_kconfigs; | 2463 | my %read_kconfigs; |
2186 | 2464 | ||
2465 | sub add_dep { | ||
2466 | # $config depends on $dep | ||
2467 | my ($config, $dep) = @_; | ||
2468 | |||
2469 | if (defined($depends{$config})) { | ||
2470 | $depends{$config} .= " " . $dep; | ||
2471 | } else { | ||
2472 | $depends{$config} = $dep; | ||
2473 | } | ||
2474 | |||
2475 | # record the number of configs depending on $dep | ||
2476 | if (defined $depcount{$dep}) { | ||
2477 | $depcount{$dep}++; | ||
2478 | } else { | ||
2479 | $depcount{$dep} = 1; | ||
2480 | } | ||
2481 | } | ||
2482 | |||
2187 | # taken from streamline_config.pl | 2483 | # taken from streamline_config.pl |
2188 | sub read_kconfig { | 2484 | sub read_kconfig { |
2189 | my ($kconfig) = @_; | 2485 | my ($kconfig) = @_; |
@@ -2230,30 +2526,19 @@ sub read_kconfig { | |||
2230 | $config = $2; | 2526 | $config = $2; |
2231 | 2527 | ||
2232 | for (my $i = 0; $i < $iflevel; $i++) { | 2528 | for (my $i = 0; $i < $iflevel; $i++) { |
2233 | if ($i) { | 2529 | add_dep $config, $ifdeps[$i]; |
2234 | $depends{$config} .= " " . $ifdeps[$i]; | ||
2235 | } else { | ||
2236 | $depends{$config} = $ifdeps[$i]; | ||
2237 | } | ||
2238 | $state = "DEP"; | ||
2239 | } | 2530 | } |
2240 | 2531 | ||
2241 | # collect the depends for the config | 2532 | # collect the depends for the config |
2242 | } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { | 2533 | } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { |
2243 | 2534 | ||
2244 | if (defined($depends{$1})) { | 2535 | add_dep $config, $1; |
2245 | $depends{$config} .= " " . $1; | ||
2246 | } else { | ||
2247 | $depends{$config} = $1; | ||
2248 | } | ||
2249 | 2536 | ||
2250 | # Get the configs that select this config | 2537 | # Get the configs that select this config |
2251 | } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) { | 2538 | } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) { |
2252 | if (defined($depends{$1})) { | 2539 | |
2253 | $depends{$1} .= " " . $config; | 2540 | # selected by depends on config |
2254 | } else { | 2541 | add_dep $1, $config; |
2255 | $depends{$1} = $config; | ||
2256 | } | ||
2257 | 2542 | ||
2258 | # Check for if statements | 2543 | # Check for if statements |
2259 | } elsif (/^if\s+(.*\S)\s*$/) { | 2544 | } elsif (/^if\s+(.*\S)\s*$/) { |
@@ -2365,11 +2650,18 @@ sub make_new_config { | |||
2365 | close OUT; | 2650 | close OUT; |
2366 | } | 2651 | } |
2367 | 2652 | ||
2653 | sub chomp_config { | ||
2654 | my ($config) = @_; | ||
2655 | |||
2656 | $config =~ s/CONFIG_//; | ||
2657 | |||
2658 | return $config; | ||
2659 | } | ||
2660 | |||
2368 | sub get_depends { | 2661 | sub get_depends { |
2369 | my ($dep) = @_; | 2662 | my ($dep) = @_; |
2370 | 2663 | ||
2371 | my $kconfig = $dep; | 2664 | my $kconfig = chomp_config $dep; |
2372 | $kconfig =~ s/CONFIG_//; | ||
2373 | 2665 | ||
2374 | $dep = $depends{"$kconfig"}; | 2666 | $dep = $depends{"$kconfig"}; |
2375 | 2667 | ||
@@ -2419,8 +2711,7 @@ sub test_this_config { | |||
2419 | return undef; | 2711 | return undef; |
2420 | } | 2712 | } |
2421 | 2713 | ||
2422 | my $kconfig = $config; | 2714 | my $kconfig = chomp_config $config; |
2423 | $kconfig =~ s/CONFIG_//; | ||
2424 | 2715 | ||
2425 | # Test dependencies first | 2716 | # Test dependencies first |
2426 | if (defined($depends{"$kconfig"})) { | 2717 | if (defined($depends{"$kconfig"})) { |
@@ -2510,6 +2801,14 @@ sub make_min_config { | |||
2510 | 2801 | ||
2511 | my @config_keys = keys %min_configs; | 2802 | my @config_keys = keys %min_configs; |
2512 | 2803 | ||
2804 | # All configs need a depcount | ||
2805 | foreach my $config (@config_keys) { | ||
2806 | my $kconfig = chomp_config $config; | ||
2807 | if (!defined $depcount{$kconfig}) { | ||
2808 | $depcount{$kconfig} = 0; | ||
2809 | } | ||
2810 | } | ||
2811 | |||
2513 | # Remove anything that was set by the make allnoconfig | 2812 | # Remove anything that was set by the make allnoconfig |
2514 | # we shouldn't need them as they get set for us anyway. | 2813 | # we shouldn't need them as they get set for us anyway. |
2515 | foreach my $config (@config_keys) { | 2814 | foreach my $config (@config_keys) { |
@@ -2548,8 +2847,13 @@ sub make_min_config { | |||
2548 | # Now disable each config one by one and do a make oldconfig | 2847 | # Now disable each config one by one and do a make oldconfig |
2549 | # till we find a config that changes our list. | 2848 | # till we find a config that changes our list. |
2550 | 2849 | ||
2551 | # Put configs that did not modify the config at the end. | ||
2552 | my @test_configs = keys %min_configs; | 2850 | my @test_configs = keys %min_configs; |
2851 | |||
2852 | # Sort keys by who is most dependent on | ||
2853 | @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} } | ||
2854 | @test_configs ; | ||
2855 | |||
2856 | # Put configs that did not modify the config at the end. | ||
2553 | my $reset = 1; | 2857 | my $reset = 1; |
2554 | for (my $i = 0; $i < $#test_configs; $i++) { | 2858 | for (my $i = 0; $i < $#test_configs; $i++) { |
2555 | if (!defined($nochange_config{$test_configs[0]})) { | 2859 | if (!defined($nochange_config{$test_configs[0]})) { |
@@ -2659,10 +2963,7 @@ sub make_min_config { | |||
2659 | } | 2963 | } |
2660 | 2964 | ||
2661 | doprint "Reboot and wait $sleep_time seconds\n"; | 2965 | doprint "Reboot and wait $sleep_time seconds\n"; |
2662 | reboot; | 2966 | reboot $sleep_time; |
2663 | start_monitor; | ||
2664 | wait_for_monitor $sleep_time; | ||
2665 | end_monitor; | ||
2666 | } | 2967 | } |
2667 | 2968 | ||
2668 | success $i; | 2969 | success $i; |
@@ -2783,6 +3084,9 @@ sub set_test_option { | |||
2783 | # First we need to do is the builds | 3084 | # First we need to do is the builds |
2784 | for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { | 3085 | for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { |
2785 | 3086 | ||
3087 | # Do not reboot on failing test options | ||
3088 | $no_reboot = 1; | ||
3089 | |||
2786 | $iteration = $i; | 3090 | $iteration = $i; |
2787 | 3091 | ||
2788 | my $makecmd = set_test_option("MAKE_CMD", $i); | 3092 | my $makecmd = set_test_option("MAKE_CMD", $i); |
@@ -2811,6 +3115,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { | |||
2811 | $reboot_type = set_test_option("REBOOT_TYPE", $i); | 3115 | $reboot_type = set_test_option("REBOOT_TYPE", $i); |
2812 | $grub_menu = set_test_option("GRUB_MENU", $i); | 3116 | $grub_menu = set_test_option("GRUB_MENU", $i); |
2813 | $post_install = set_test_option("POST_INSTALL", $i); | 3117 | $post_install = set_test_option("POST_INSTALL", $i); |
3118 | $no_install = set_test_option("NO_INSTALL", $i); | ||
2814 | $reboot_script = set_test_option("REBOOT_SCRIPT", $i); | 3119 | $reboot_script = set_test_option("REBOOT_SCRIPT", $i); |
2815 | $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); | 3120 | $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); |
2816 | $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); | 3121 | $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); |
@@ -2832,6 +3137,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { | |||
2832 | $console = set_test_option("CONSOLE", $i); | 3137 | $console = set_test_option("CONSOLE", $i); |
2833 | $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i); | 3138 | $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i); |
2834 | $success_line = set_test_option("SUCCESS_LINE", $i); | 3139 | $success_line = set_test_option("SUCCESS_LINE", $i); |
3140 | $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i); | ||
2835 | $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i); | 3141 | $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i); |
2836 | $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i); | 3142 | $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i); |
2837 | $stop_test_after = set_test_option("STOP_TEST_AFTER", $i); | 3143 | $stop_test_after = set_test_option("STOP_TEST_AFTER", $i); |
@@ -2850,9 +3156,11 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { | |||
2850 | 3156 | ||
2851 | chdir $builddir || die "can't change directory to $builddir"; | 3157 | chdir $builddir || die "can't change directory to $builddir"; |
2852 | 3158 | ||
2853 | if (!-d $tmpdir) { | 3159 | foreach my $dir ($tmpdir, $outputdir) { |
2854 | mkpath($tmpdir) or | 3160 | if (!-d $dir) { |
2855 | die "can't create $tmpdir"; | 3161 | mkpath($dir) or |
3162 | die "can't create $dir"; | ||
3163 | } | ||
2856 | } | 3164 | } |
2857 | 3165 | ||
2858 | $ENV{"SSH_USER"} = $ssh_user; | 3166 | $ENV{"SSH_USER"} = $ssh_user; |
@@ -2889,8 +3197,11 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { | |||
2889 | $run_type = "ERROR"; | 3197 | $run_type = "ERROR"; |
2890 | } | 3198 | } |
2891 | 3199 | ||
3200 | my $installme = ""; | ||
3201 | $installme = " no_install" if ($no_install); | ||
3202 | |||
2892 | doprint "\n\n"; | 3203 | doprint "\n\n"; |
2893 | doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n"; | 3204 | doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n"; |
2894 | 3205 | ||
2895 | unlink $dmesg; | 3206 | unlink $dmesg; |
2896 | unlink $buildlog; | 3207 | unlink $buildlog; |
@@ -2911,6 +3222,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { | |||
2911 | die "failed to checkout $checkout"; | 3222 | die "failed to checkout $checkout"; |
2912 | } | 3223 | } |
2913 | 3224 | ||
3225 | $no_reboot = 0; | ||
3226 | |||
3227 | |||
2914 | if ($test_type eq "bisect") { | 3228 | if ($test_type eq "bisect") { |
2915 | bisect $i; | 3229 | bisect $i; |
2916 | next; | 3230 | next; |
@@ -2929,6 +3243,13 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { | |||
2929 | build $build_type or next; | 3243 | build $build_type or next; |
2930 | } | 3244 | } |
2931 | 3245 | ||
3246 | if ($test_type eq "install") { | ||
3247 | get_version; | ||
3248 | install; | ||
3249 | success $i; | ||
3250 | next; | ||
3251 | } | ||
3252 | |||
2932 | if ($test_type ne "build") { | 3253 | if ($test_type ne "build") { |
2933 | my $failed = 0; | 3254 | my $failed = 0; |
2934 | start_monitor_and_boot or $failed = 1; | 3255 | start_monitor_and_boot or $failed = 1; |