#default opts
$default{"NUM_TESTS"} = 1;
-$default{"REBOOT_TYPE"} = "grub";
-$default{"TEST_TYPE"} = "test";
+$default{"TEST_TYPE"} = "build";
$default{"BUILD_TYPE"} = "randconfig";
$default{"MAKE_CMD"} = "make";
$default{"TIMEOUT"} = 120;
$default{"STOP_AFTER_SUCCESS"} = 10;
$default{"STOP_AFTER_FAILURE"} = 60;
$default{"STOP_TEST_AFTER"} = 600;
+
+# required, and we will ask users if they don't have them but we keep the default
+# value something that is common.
+$default{"REBOOT_TYPE"} = "grub";
$default{"LOCALVERSION"} = "-test";
+$default{"SSH_USER"} = "root";
+$default{"BUILD_TARGET"} = "arch/x86/boot/bzImage";
+$default{"TARGET_IMAGE"} = "/boot/vmlinuz-test";
my $ktest_config;
my $version;
my $run_test;
my $redirect;
my $buildlog;
+my $testlog;
my $dmesg;
my $monitor_fp;
my $monitor_pid;
my $patchcheck_sleep_time;
my $ignore_warnings;
my $store_failures;
+my $store_successes;
my $test_name;
my $timeout;
my $booted_timeout;
my $iteration = 0;
my $successes = 0;
+# set when a test is something other that just building
+# which would require more options.
+my $buildonly = 1;
+
my %entered_configs;
my %config_help;
my %variable;
$config_help{"MACHINE"} = << "EOF"
The machine hostname that you will test.
+ For build only tests, it is still needed to differentiate log files.
EOF
;
$config_help{"SSH_USER"} = << "EOF"
;
$config_help{"BUILD_DIR"} = << "EOF"
The directory that contains the Linux source code (full path).
+ You can use \${PWD} that will be the path where ktest.pl is run, or use
+ \${THIS_DIR} which is assigned \${PWD} but may be changed later.
EOF
;
$config_help{"OUTPUT_DIR"} = << "EOF"
The directory that the objects will be built (full path).
(can not be same as BUILD_DIR)
+ You can use \${PWD} that will be the path where ktest.pl is run, or use
+ \${THIS_DIR} which is assigned \${PWD} but may be changed later.
EOF
;
$config_help{"BUILD_TARGET"} = << "EOF"
EOF
;
-sub read_yn {
- my ($prompt) = @_;
+sub read_prompt {
+ my ($cancel, $prompt) = @_;
my $ans;
for (;;) {
- print "$prompt [Y/n] ";
+ if ($cancel) {
+ print "$prompt [y/n/C] ";
+ } else {
+ print "$prompt [Y/n] ";
+ }
$ans = <STDIN>;
chomp $ans;
if ($ans =~ /^\s*$/) {
- $ans = "y";
+ if ($cancel) {
+ $ans = "c";
+ } else {
+ $ans = "y";
+ }
}
last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
- print "Please answer either 'y' or 'n'.\n";
+ if ($cancel) {
+ last if ($ans =~ /^c$/i);
+ print "Please answer either 'y', 'n' or 'c'.\n";
+ } else {
+ print "Please answer either 'y' or 'n'.\n";
+ }
+ }
+ if ($ans =~ /^c/i) {
+ exit;
}
if ($ans !~ /^y$/i) {
return 0;
return 1;
}
+sub read_yn {
+ my ($prompt) = @_;
+
+ return read_prompt 0, $prompt;
+}
+
+sub read_ync {
+ my ($prompt) = @_;
+
+ return read_prompt 1, $prompt;
+}
+
sub get_ktest_config {
my ($config) = @_;
my $ans;
next;
}
}
- $entered_configs{$config} = process_variables($ans);
+ $entered_configs{$config} = ${ans};
last;
}
}
sub get_ktest_configs {
get_ktest_config("MACHINE");
- get_ktest_config("SSH_USER");
get_ktest_config("BUILD_DIR");
get_ktest_config("OUTPUT_DIR");
- get_ktest_config("BUILD_TARGET");
- get_ktest_config("TARGET_IMAGE");
- get_ktest_config("POWER_CYCLE");
- get_ktest_config("CONSOLE");
+
+ # options required for other than just building a kernel
+ if (!$buildonly) {
+ get_ktest_config("SSH_USER");
+ get_ktest_config("BUILD_TARGET");
+ get_ktest_config("TARGET_IMAGE");
+ get_ktest_config("POWER_CYCLE");
+ get_ktest_config("CONSOLE");
+ }
+
get_ktest_config("LOCALVERSION");
+ return if ($buildonly);
+
my $rtype = $opt{"REBOOT_TYPE"};
if (!defined($rtype)) {
sub set_value {
my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
+ if ($lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $rvalue ne "build") {
+ # Note if a test is something other than build, then we
+ # will need other manditory options.
+ $buildonly = 0;
+ }
+
if (defined($opt{$lvalue})) {
if (!$override || defined(${$overrides}{$lvalue})) {
my $extra = "";
return $test_case;
}
+sub get_test_case {
+ print "What test case would you like to run?\n";
+ print " (build, install or boot)\n";
+ print " Other tests are available but require editing the config file\n";
+ my $ans = <STDIN>;
+ chomp $ans;
+ $default{"TEST_TYPE"} = $ans;
+}
+
sub read_config {
my ($config) = @_;
# was a test specified?
if (!$test_case) {
print "No test case specified.\n";
- print "What test case would you like to run?\n";
- my $ans = <STDIN>;
- chomp $ans;
- $default{"TEST_TYPE"} = $ans;
+ get_test_case;
}
# set any defaults
# Add space to evaluate the character before $
$option = " $option";
my $retval = "";
+ my $repeated = 0;
+ my $parent = 0;
+
+ foreach my $test (keys %repeat_tests) {
+ if ($i >= $test &&
+ $i < $test + $repeat_tests{$test}) {
+
+ $repeated = 1;
+ $parent = $test;
+ last;
+ }
+ }
while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
my $start = $1;
# otherwise see if the default OPT (without [$i]) exists.
my $o = "$var\[$i\]";
+ my $parento = "$var\[$parent\]";
if (defined($opt{$o})) {
$o = $opt{$o};
$retval = "$retval$o";
+ } elsif ($repeated && defined($opt{$parento})) {
+ $o = $opt{$parento};
+ $retval = "$retval$o";
} elsif (defined($opt{$var})) {
$o = $opt{$var};
$retval = "$retval$o";
print "** Monitor flushed **\n";
}
+sub save_logs {
+ my ($result, $basedir) = @_;
+ my @t = localtime;
+ my $date = sprintf "%04d%02d%02d%02d%02d%02d",
+ 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
+
+ my $type = $build_type;
+ if ($type =~ /useconfig/) {
+ $type = "useconfig";
+ }
+
+ my $dir = "$machine-$test_type-$type-$result-$date";
+
+ $dir = "$basedir/$dir";
+
+ if (!-d $dir) {
+ mkpath($dir) or
+ die "can't create $dir";
+ }
+
+ my %files = (
+ "config" => $output_config,
+ "buildlog" => $buildlog,
+ "dmesg" => $dmesg,
+ "testlog" => $testlog,
+ );
+
+ while (my ($name, $source) = each(%files)) {
+ if (-f "$source") {
+ cp "$source", "$dir/$name" or
+ die "failed to copy $source";
+ }
+ }
+
+ doprint "*** Saved info to $dir ***\n";
+}
+
sub fail {
if ($die_on_failure) {
doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
- return 1 if (!defined($store_failures));
-
- my @t = localtime;
- my $date = sprintf "%04d%02d%02d%02d%02d%02d",
- 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
-
- my $type = $build_type;
- if ($type =~ /useconfig/) {
- $type = "useconfig";
- }
-
- my $dir = "$machine-$test_type-$type-fail-$date";
- my $faildir = "$store_failures/$dir";
-
- if (!-d $faildir) {
- mkpath($faildir) or
- die "can't create $faildir";
- }
- if (-f "$output_config") {
- cp "$output_config", "$faildir/config" or
- die "failed to copy .config";
- }
- if (-f $buildlog) {
- cp $buildlog, "$faildir/buildlog" or
- die "failed to move $buildlog";
- }
- if (-f $dmesg) {
- cp $dmesg, "$faildir/dmesg" or
- die "failed to move $dmesg";
- }
-
- doprint "*** Saved info to $faildir ***\n";
+ if (defined($store_failures)) {
+ save_logs "fail", $store_failures;
+ }
return 1;
}
doprint "*******************************************\n";
doprint "*******************************************\n";
+ if (defined($store_successes)) {
+ save_logs "success", $store_successes;
+ }
+
if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
doprint "Reboot and wait $sleep_time seconds\n";
reboot $sleep_time;
$poweroff_on_error = 0;
$die_on_failure = 1;
+ $redirect = "$testlog";
run_command $run_test or $failed = 1;
+ undef $redirect;
+
exit $failed;
}
}
}
+sub update_bisect_replay {
+ my $tmp_log = "$tmpdir/ktest_bisect_log";
+ run_command "git bisect log > $tmp_log" or
+ die "can't create bisect log";
+ return $tmp_log;
+}
+
sub bisect {
my ($i) = @_;
$type = "boot";
}
+ # Check if a bisect was running
+ my $bisect_start_file = "$builddir/.git/BISECT_START";
+
my $check = $opt{"BISECT_CHECK[$i]"};
- if (defined($check) && $check ne "0") {
+ my $do_check = defined($check) && $check ne "0";
+
+ if ( -f $bisect_start_file ) {
+ print "Bisect in progress found\n";
+ if ($do_check) {
+ print " If you say yes, then no checks of good or bad will be done\n";
+ }
+ if (defined($replay)) {
+ print "** BISECT_REPLAY is defined in config file **";
+ print " Ignore config option and perform new git bisect log?\n";
+ if (read_ync " (yes, no, or cancel) ") {
+ $replay = update_bisect_replay;
+ $do_check = 0;
+ }
+ } elsif (read_yn "read git log and continue?") {
+ $replay = update_bisect_replay;
+ $do_check = 0;
+ }
+ }
+
+ if ($do_check) {
# get current HEAD
my $head = get_sha1("HEAD");
}
if (! -f $ktest_config) {
+ get_test_case;
open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
print OUT << "EOF"
# Generated by ktest.pl
#
+
+# PWD is a ktest.pl variable that will result in the process working
+# directory that ktest.pl is executed in.
+
+# THIS_DIR is automatically assigned the PWD of the path that generated
+# the config file. It is best to use this variable when assigning other
+# directory paths within this directory. This allows you to easily
+# move the test cases to other locations or to other machines.
+#
+THIS_DIR := $variable{"PWD"}
+
# Define each test with TEST_START
# The config options below it will override the defaults
TEST_START
+TEST_TYPE = $default{"TEST_TYPE"}
DEFAULTS
EOF
open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
foreach my $config (@new_configs) {
print OUT "$config = $entered_configs{$config}\n";
- $opt{$config} = $entered_configs{$config};
+ $opt{$config} = process_variables($entered_configs{$config});
}
}
$bisect_skip = set_test_option("BISECT_SKIP", $i);
$config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
$store_failures = set_test_option("STORE_FAILURES", $i);
+ $store_successes = set_test_option("STORE_SUCCESSES", $i);
$test_name = set_test_option("TEST_NAME", $i);
$timeout = set_test_option("TIMEOUT", $i);
$booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
$ENV{"SSH_USER"} = $ssh_user;
$ENV{"MACHINE"} = $machine;
- $target = "$ssh_user\@$machine";
-
$buildlog = "$tmpdir/buildlog-$machine";
+ $testlog = "$tmpdir/testlog-$machine";
$dmesg = "$tmpdir/dmesg-$machine";
$make = "$makecmd O=$outputdir";
$output_config = "$outputdir/.config";
- if ($reboot_type eq "grub") {
- dodie "GRUB_MENU not defined" if (!defined($grub_menu));
- } elsif (!defined($reboot_script)) {
- dodie "REBOOT_SCRIPT not defined"
+ if (!$buildonly) {
+ $target = "$ssh_user\@$machine";
+ if ($reboot_type eq "grub") {
+ dodie "GRUB_MENU not defined" if (!defined($grub_menu));
+ } elsif (!defined($reboot_script)) {
+ dodie "REBOOT_SCRIPT not defined"
+ }
}
my $run_type = $build_type;
unlink $dmesg;
unlink $buildlog;
+ unlink $testlog;
if (defined($addconfig)) {
my $min = $minconfig;