|
@@ -18,6 +18,7 @@ $| = 1;
|
|
my %opt;
|
|
my %opt;
|
|
my %repeat_tests;
|
|
my %repeat_tests;
|
|
my %repeats;
|
|
my %repeats;
|
|
|
|
+my %evals;
|
|
|
|
|
|
#default opts
|
|
#default opts
|
|
my %default = (
|
|
my %default = (
|
|
@@ -25,6 +26,7 @@ my %default = (
|
|
"TEST_TYPE" => "build",
|
|
"TEST_TYPE" => "build",
|
|
"BUILD_TYPE" => "randconfig",
|
|
"BUILD_TYPE" => "randconfig",
|
|
"MAKE_CMD" => "make",
|
|
"MAKE_CMD" => "make",
|
|
|
|
+ "CLOSE_CONSOLE_SIGNAL" => "INT",
|
|
"TIMEOUT" => 120,
|
|
"TIMEOUT" => 120,
|
|
"TMP_DIR" => "/tmp/ktest/\${MACHINE}",
|
|
"TMP_DIR" => "/tmp/ktest/\${MACHINE}",
|
|
"SLEEP_TIME" => 60, # sleep time between tests
|
|
"SLEEP_TIME" => 60, # sleep time between tests
|
|
@@ -39,6 +41,7 @@ my %default = (
|
|
"CLEAR_LOG" => 0,
|
|
"CLEAR_LOG" => 0,
|
|
"BISECT_MANUAL" => 0,
|
|
"BISECT_MANUAL" => 0,
|
|
"BISECT_SKIP" => 1,
|
|
"BISECT_SKIP" => 1,
|
|
|
|
+ "BISECT_TRIES" => 1,
|
|
"MIN_CONFIG_TYPE" => "boot",
|
|
"MIN_CONFIG_TYPE" => "boot",
|
|
"SUCCESS_LINE" => "login:",
|
|
"SUCCESS_LINE" => "login:",
|
|
"DETECT_TRIPLE_FAULT" => 1,
|
|
"DETECT_TRIPLE_FAULT" => 1,
|
|
@@ -137,6 +140,7 @@ my $bisect_bad_commit = "";
|
|
my $reverse_bisect;
|
|
my $reverse_bisect;
|
|
my $bisect_manual;
|
|
my $bisect_manual;
|
|
my $bisect_skip;
|
|
my $bisect_skip;
|
|
|
|
+my $bisect_tries;
|
|
my $config_bisect_good;
|
|
my $config_bisect_good;
|
|
my $bisect_ret_good;
|
|
my $bisect_ret_good;
|
|
my $bisect_ret_bad;
|
|
my $bisect_ret_bad;
|
|
@@ -163,6 +167,7 @@ my $timeout;
|
|
my $booted_timeout;
|
|
my $booted_timeout;
|
|
my $detect_triplefault;
|
|
my $detect_triplefault;
|
|
my $console;
|
|
my $console;
|
|
|
|
+my $close_console_signal;
|
|
my $reboot_success_line;
|
|
my $reboot_success_line;
|
|
my $success_line;
|
|
my $success_line;
|
|
my $stop_after_success;
|
|
my $stop_after_success;
|
|
@@ -273,6 +278,7 @@ my %option_map = (
|
|
"IGNORE_ERRORS" => \$ignore_errors,
|
|
"IGNORE_ERRORS" => \$ignore_errors,
|
|
"BISECT_MANUAL" => \$bisect_manual,
|
|
"BISECT_MANUAL" => \$bisect_manual,
|
|
"BISECT_SKIP" => \$bisect_skip,
|
|
"BISECT_SKIP" => \$bisect_skip,
|
|
|
|
+ "BISECT_TRIES" => \$bisect_tries,
|
|
"CONFIG_BISECT_GOOD" => \$config_bisect_good,
|
|
"CONFIG_BISECT_GOOD" => \$config_bisect_good,
|
|
"BISECT_RET_GOOD" => \$bisect_ret_good,
|
|
"BISECT_RET_GOOD" => \$bisect_ret_good,
|
|
"BISECT_RET_BAD" => \$bisect_ret_bad,
|
|
"BISECT_RET_BAD" => \$bisect_ret_bad,
|
|
@@ -285,6 +291,7 @@ my %option_map = (
|
|
"TIMEOUT" => \$timeout,
|
|
"TIMEOUT" => \$timeout,
|
|
"BOOTED_TIMEOUT" => \$booted_timeout,
|
|
"BOOTED_TIMEOUT" => \$booted_timeout,
|
|
"CONSOLE" => \$console,
|
|
"CONSOLE" => \$console,
|
|
|
|
+ "CLOSE_CONSOLE_SIGNAL" => \$close_console_signal,
|
|
"DETECT_TRIPLE_FAULT" => \$detect_triplefault,
|
|
"DETECT_TRIPLE_FAULT" => \$detect_triplefault,
|
|
"SUCCESS_LINE" => \$success_line,
|
|
"SUCCESS_LINE" => \$success_line,
|
|
"REBOOT_SUCCESS_LINE" => \$reboot_success_line,
|
|
"REBOOT_SUCCESS_LINE" => \$reboot_success_line,
|
|
@@ -445,6 +452,27 @@ $config_help{"REBOOT_SCRIPT"} = << "EOF"
|
|
EOF
|
|
EOF
|
|
;
|
|
;
|
|
|
|
|
|
|
|
+sub _logit {
|
|
|
|
+ if (defined($opt{"LOG_FILE"})) {
|
|
|
|
+ open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
|
|
|
|
+ print OUT @_;
|
|
|
|
+ close(OUT);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+sub logit {
|
|
|
|
+ if (defined($opt{"LOG_FILE"})) {
|
|
|
|
+ _logit @_;
|
|
|
|
+ } else {
|
|
|
|
+ print @_;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+sub doprint {
|
|
|
|
+ print @_;
|
|
|
|
+ _logit @_;
|
|
|
|
+}
|
|
|
|
+
|
|
sub read_prompt {
|
|
sub read_prompt {
|
|
my ($cancel, $prompt) = @_;
|
|
my ($cancel, $prompt) = @_;
|
|
|
|
|
|
@@ -662,6 +690,22 @@ sub set_value {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+sub set_eval {
|
|
|
|
+ my ($lvalue, $rvalue, $name) = @_;
|
|
|
|
+
|
|
|
|
+ my $prvalue = process_variables($rvalue);
|
|
|
|
+ my $arr;
|
|
|
|
+
|
|
|
|
+ if (defined($evals{$lvalue})) {
|
|
|
|
+ $arr = $evals{$lvalue};
|
|
|
|
+ } else {
|
|
|
|
+ $arr = [];
|
|
|
|
+ $evals{$lvalue} = $arr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ push @{$arr}, $rvalue;
|
|
|
|
+}
|
|
|
|
+
|
|
sub set_variable {
|
|
sub set_variable {
|
|
my ($lvalue, $rvalue) = @_;
|
|
my ($lvalue, $rvalue) = @_;
|
|
|
|
|
|
@@ -947,6 +991,20 @@ sub __read_config {
|
|
$test_case = 1;
|
|
$test_case = 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ } elsif (/^\s*([A-Z_\[\]\d]+)\s*=~\s*(.*?)\s*$/) {
|
|
|
|
+
|
|
|
|
+ next if ($skip);
|
|
|
|
+
|
|
|
|
+ my $lvalue = $1;
|
|
|
|
+ my $rvalue = $2;
|
|
|
|
+
|
|
|
|
+ if ($default || $lvalue =~ /\[\d+\]$/) {
|
|
|
|
+ set_eval($lvalue, $rvalue, $name);
|
|
|
|
+ } else {
|
|
|
|
+ my $val = "$lvalue\[$test_num\]";
|
|
|
|
+ set_eval($val, $rvalue, $name);
|
|
|
|
+ }
|
|
|
|
+
|
|
} elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
|
|
} elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
|
|
|
|
|
|
next if ($skip);
|
|
next if ($skip);
|
|
@@ -1126,6 +1184,10 @@ sub __eval_option {
|
|
} elsif (defined($opt{$var})) {
|
|
} elsif (defined($opt{$var})) {
|
|
$o = $opt{$var};
|
|
$o = $opt{$var};
|
|
$retval = "$retval$o";
|
|
$retval = "$retval$o";
|
|
|
|
+ } elsif ($var eq "KERNEL_VERSION" && defined($make)) {
|
|
|
|
+ # special option KERNEL_VERSION uses kernel version
|
|
|
|
+ get_version();
|
|
|
|
+ $retval = "$retval$version";
|
|
} else {
|
|
} else {
|
|
$retval = "$retval\$\{$var\}";
|
|
$retval = "$retval\$\{$var\}";
|
|
}
|
|
}
|
|
@@ -1140,6 +1202,33 @@ sub __eval_option {
|
|
return $retval;
|
|
return $retval;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+sub process_evals {
|
|
|
|
+ my ($name, $option, $i) = @_;
|
|
|
|
+
|
|
|
|
+ my $option_name = "$name\[$i\]";
|
|
|
|
+ my $ev;
|
|
|
|
+
|
|
|
|
+ my $old_option = $option;
|
|
|
|
+
|
|
|
|
+ if (defined($evals{$option_name})) {
|
|
|
|
+ $ev = $evals{$option_name};
|
|
|
|
+ } elsif (defined($evals{$name})) {
|
|
|
|
+ $ev = $evals{$name};
|
|
|
|
+ } else {
|
|
|
|
+ return $option;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for my $e (@{$ev}) {
|
|
|
|
+ eval "\$option =~ $e";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ($option ne $old_option) {
|
|
|
|
+ doprint("$name changed from '$old_option' to '$option'\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return $option;
|
|
|
|
+}
|
|
|
|
+
|
|
sub eval_option {
|
|
sub eval_option {
|
|
my ($name, $option, $i) = @_;
|
|
my ($name, $option, $i) = @_;
|
|
|
|
|
|
@@ -1160,28 +1249,9 @@ sub eval_option {
|
|
$option = __eval_option($name, $option, $i);
|
|
$option = __eval_option($name, $option, $i);
|
|
}
|
|
}
|
|
|
|
|
|
- return $option;
|
|
|
|
-}
|
|
|
|
|
|
+ $option = process_evals($name, $option, $i);
|
|
|
|
|
|
-sub _logit {
|
|
|
|
- if (defined($opt{"LOG_FILE"})) {
|
|
|
|
- open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
|
|
|
|
- print OUT @_;
|
|
|
|
- close(OUT);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-sub logit {
|
|
|
|
- if (defined($opt{"LOG_FILE"})) {
|
|
|
|
- _logit @_;
|
|
|
|
- } else {
|
|
|
|
- print @_;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-sub doprint {
|
|
|
|
- print @_;
|
|
|
|
- _logit @_;
|
|
|
|
|
|
+ return $option;
|
|
}
|
|
}
|
|
|
|
|
|
sub run_command;
|
|
sub run_command;
|
|
@@ -1296,7 +1366,7 @@ sub close_console {
|
|
my ($fp, $pid) = @_;
|
|
my ($fp, $pid) = @_;
|
|
|
|
|
|
doprint "kill child process $pid\n";
|
|
doprint "kill child process $pid\n";
|
|
- kill 2, $pid;
|
|
|
|
|
|
+ kill $close_console_signal, $pid;
|
|
|
|
|
|
print "closing!\n";
|
|
print "closing!\n";
|
|
close($fp);
|
|
close($fp);
|
|
@@ -2517,12 +2587,29 @@ sub run_bisect {
|
|
$buildtype = "useconfig:$minconfig";
|
|
$buildtype = "useconfig:$minconfig";
|
|
}
|
|
}
|
|
|
|
|
|
- my $ret = run_bisect_test $type, $buildtype;
|
|
|
|
|
|
+ # If the user sets bisect_tries to less than 1, then no tries
|
|
|
|
+ # is a success.
|
|
|
|
+ my $ret = 1;
|
|
|
|
|
|
- if ($bisect_manual) {
|
|
|
|
|
|
+ # Still let the user manually decide that though.
|
|
|
|
+ if ($bisect_tries < 1 && $bisect_manual) {
|
|
$ret = answer_bisect;
|
|
$ret = answer_bisect;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ for (my $i = 0; $i < $bisect_tries; $i++) {
|
|
|
|
+ if ($bisect_tries > 1) {
|
|
|
|
+ my $t = $i + 1;
|
|
|
|
+ doprint("Running bisect trial $t of $bisect_tries:\n");
|
|
|
|
+ }
|
|
|
|
+ $ret = run_bisect_test $type, $buildtype;
|
|
|
|
+
|
|
|
|
+ if ($bisect_manual) {
|
|
|
|
+ $ret = answer_bisect;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ last if (!$ret);
|
|
|
|
+ }
|
|
|
|
+
|
|
# Are we looking for where it worked, not failed?
|
|
# Are we looking for where it worked, not failed?
|
|
if ($reverse_bisect && $ret >= 0) {
|
|
if ($reverse_bisect && $ret >= 0) {
|
|
$ret = !$ret;
|
|
$ret = !$ret;
|
|
@@ -3916,6 +4003,18 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
|
|
|
|
|
|
my $makecmd = set_test_option("MAKE_CMD", $i);
|
|
my $makecmd = set_test_option("MAKE_CMD", $i);
|
|
|
|
|
|
|
|
+ $outputdir = set_test_option("OUTPUT_DIR", $i);
|
|
|
|
+ $builddir = set_test_option("BUILD_DIR", $i);
|
|
|
|
+
|
|
|
|
+ chdir $builddir || die "can't change directory to $builddir";
|
|
|
|
+
|
|
|
|
+ if (!-d $outputdir) {
|
|
|
|
+ mkpath($outputdir) or
|
|
|
|
+ die "can't create $outputdir";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $make = "$makecmd O=$outputdir";
|
|
|
|
+
|
|
# Load all the options into their mapped variable names
|
|
# Load all the options into their mapped variable names
|
|
foreach my $opt (keys %option_map) {
|
|
foreach my $opt (keys %option_map) {
|
|
${$option_map{$opt}} = set_test_option($opt, $i);
|
|
${$option_map{$opt}} = set_test_option($opt, $i);
|
|
@@ -3940,13 +4039,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
|
|
$start_minconfig = $minconfig;
|
|
$start_minconfig = $minconfig;
|
|
}
|
|
}
|
|
|
|
|
|
- chdir $builddir || die "can't change directory to $builddir";
|
|
|
|
-
|
|
|
|
- foreach my $dir ($tmpdir, $outputdir) {
|
|
|
|
- if (!-d $dir) {
|
|
|
|
- mkpath($dir) or
|
|
|
|
- die "can't create $dir";
|
|
|
|
- }
|
|
|
|
|
|
+ if (!-d $tmpdir) {
|
|
|
|
+ mkpath($tmpdir) or
|
|
|
|
+ die "can't create $tmpdir";
|
|
}
|
|
}
|
|
|
|
|
|
$ENV{"SSH_USER"} = $ssh_user;
|
|
$ENV{"SSH_USER"} = $ssh_user;
|
|
@@ -3955,7 +4050,6 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
|
|
$buildlog = "$tmpdir/buildlog-$machine";
|
|
$buildlog = "$tmpdir/buildlog-$machine";
|
|
$testlog = "$tmpdir/testlog-$machine";
|
|
$testlog = "$tmpdir/testlog-$machine";
|
|
$dmesg = "$tmpdir/dmesg-$machine";
|
|
$dmesg = "$tmpdir/dmesg-$machine";
|
|
- $make = "$makecmd O=$outputdir";
|
|
|
|
$output_config = "$outputdir/.config";
|
|
$output_config = "$outputdir/.config";
|
|
|
|
|
|
if (!$buildonly) {
|
|
if (!$buildonly) {
|