Skip to content

Commit 5ed1957

Browse files
committed
Merge tag 'ktest-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-ktest
Pull ktest updates from Steven Rostedt: - Fix undef warning when WARNINGS_FILE is unset The check_buildlog() references WARNINGS_FILE even when it's not set. Perl triggers a warning in this case. Check if the WARNINGS_FILE is defined before checking if the file it represents exists. - Fix how LOG_FILE is resolved LOG_FILE is expanded immediately after the config file is parsed. If LOG_FILE depends on variables from the tests it will use stale values instead of using the test variables. Have LOG_FILE also resolve test variables. - Treat a undefined self reference variable as empty Variables can recursively include itself for appending. Currently, if the references itself and it is not defined, it leaves the variable in the define: "VAR = ${VAR} foo" keeps the ${VAR} around. Have it removed instead. - Fix clearing of variables per tests If a variable has a defined default, a test can not clear it by assigning the variable to empty. Fix this by clearing the variable for a test when the test config has that variable assigned to nothing. - Fix run_command() to catch stderr in the shell command parsing Switch to Perl list form open to use "sh -c" wrapper to run shell commands to have the log file catch shell parsing errors. - Fix console output during reboot cycle The POWER_CYCLE callback during reboot() can miss output from the next boot making ktest miss the boot string it was waiting for. - Add PRE_KTEST_DIE for PRE_KTEST failures If the command for PRE_KTEST fails, ktest does not fail (this was by design as this command was used to add patches that may or may not apply). Add PRE_KTEST_DIE value to force ktest to fail if PRE_KTEST fails. - Run POST_KTEST hooks on failure and cancellation PRE_KTEST always runs before a ktest test, have POST_KTEST always run after a test even if the test fails or is cancelled to do the teardown of PRE_KTEST. - Add a --dry-run mode Add --dry-run to parse the config, print the results and exit without running any of the tests. - Store failures from the dodie() path as well The STORE_FAILURES saves the logs on failure, but there's failure paths that miss storing. Perform STORE_FAILURES in dodie() to capture these failures too. * tag 'ktest-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-ktest: ktest: Store failure logs also in fatal paths ktest: Add a --dry-run mode ktest: Run POST_KTEST hooks on failure and cancellation ktest: Add PRE_KTEST_DIE for PRE_KTEST failures ktest: Stop dropping console output during power-cycle reboot ktest: Run commands through list-form shell open ktest: Honor empty per-test option overrides ktest: Treat undefined self-reference as empty ktest: Resolve LOG_FILE in test option context ktest: Avoid undef warning when WARNINGS_FILE is unset
2 parents b7f8496 + 81fca70 commit 5ed1957

2 files changed

Lines changed: 127 additions & 42 deletions

File tree

tools/testing/ktest/ktest.pl

Lines changed: 121 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
);
8686

8787
my $test_log_start = 0;
88+
my $dry_run = 0;
8889

8990
my $ktest_config = "ktest.conf";
9091
my $version;
@@ -100,7 +101,9 @@
100101
my $build_type;
101102
my $build_options;
102103
my $final_post_ktest;
104+
my $post_ktest_done = 0;
103105
my $pre_ktest;
106+
my $pre_ktest_die;
104107
my $post_ktest;
105108
my $pre_test;
106109
my $pre_test_die;
@@ -283,6 +286,7 @@
283286
"BUILD_DIR" => \$builddir,
284287
"TEST_TYPE" => \$test_type,
285288
"PRE_KTEST" => \$pre_ktest,
289+
"PRE_KTEST_DIE" => \$pre_ktest_die,
286290
"POST_KTEST" => \$post_ktest,
287291
"PRE_TEST" => \$pre_test,
288292
"PRE_TEST_DIE" => \$pre_test_die,
@@ -584,7 +588,7 @@
584588
sub wait_for_monitor;
585589

586590
sub _logit {
587-
if (defined($opt{"LOG_FILE"})) {
591+
if (defined($opt{"LOG_FILE"}) && defined(fileno(LOG))) {
588592
print LOG @_;
589593
}
590594
}
@@ -910,6 +914,14 @@ sub set_variable {
910914
if (defined($command_tmp_vars{$lvalue})) {
911915
return;
912916
}
917+
918+
# If a variable is undefined, treat an unescaped self-reference as empty.
919+
if (!defined($variable{$lvalue})) {
920+
$rvalue =~ s/(?<!\\)\$\{\Q$lvalue\E\}//g;
921+
$rvalue =~ s/^\s+//;
922+
$rvalue =~ s/\s+$//;
923+
}
924+
913925
if ($rvalue =~ /^\s*$/) {
914926
delete $variable{$lvalue};
915927
} else {
@@ -1354,6 +1366,9 @@ sub read_config {
13541366
print "$option\n";
13551367
}
13561368
print "Set IGNORE_UNUSED = 1 to have ktest ignore unused variables\n";
1369+
if ($dry_run) {
1370+
return;
1371+
}
13571372
if (!read_yn "Do you want to continue?") {
13581373
exit -1;
13591374
}
@@ -1491,12 +1506,13 @@ sub reboot {
14911506
}
14921507

14931508
if ($powercycle) {
1494-
run_command "$power_cycle";
1495-
14961509
start_monitor;
1497-
# flush out current monitor
1498-
# May contain the reboot success line
1499-
wait_for_monitor 1;
1510+
if (defined($time)) {
1511+
# Flush stale console output from the old kernel before power-cycling.
1512+
wait_for_monitor 1;
1513+
}
1514+
1515+
run_command "$power_cycle";
15001516

15011517
} else {
15021518
# Make sure everything has been written to disk
@@ -1575,6 +1591,24 @@ ()
15751591
return $name;
15761592
}
15771593

1594+
sub run_post_ktest {
1595+
my $cmd;
1596+
1597+
return if ($post_ktest_done);
1598+
1599+
if (defined($final_post_ktest)) {
1600+
$cmd = $final_post_ktest;
1601+
} elsif (defined($post_ktest)) {
1602+
$cmd = $post_ktest;
1603+
} else {
1604+
return;
1605+
}
1606+
1607+
my $cp_post_ktest = eval_kernel_version($cmd);
1608+
run_command $cp_post_ktest;
1609+
$post_ktest_done = 1;
1610+
}
1611+
15781612
sub dodie {
15791613
# avoid recursion
15801614
return if ($in_die);
@@ -1601,6 +1635,11 @@ sub dodie {
16011635
print " See $opt{LOG_FILE} for more info.\n";
16021636
}
16031637

1638+
# Fatal paths bypass fail(), so STORE_FAILURES needs to be handled here.
1639+
if (defined($store_failures)) {
1640+
save_logs("fail", $store_failures);
1641+
}
1642+
16041643
if ($email_on_error) {
16051644
my $name = get_test_name;
16061645
my $log_file;
@@ -1634,6 +1673,7 @@ sub dodie {
16341673
if (defined($post_test)) {
16351674
run_command $post_test;
16361675
}
1676+
run_post_ktest;
16371677

16381678
die @_, "\n";
16391679
}
@@ -1913,7 +1953,10 @@ sub run_command {
19131953
doprint("$command ... ");
19141954
$start_time = time;
19151955

1916-
$pid = open(CMD, "$command 2>&1 |") or
1956+
$pid = open(CMD, "-|",
1957+
"sh", "-c",
1958+
'command=$1; shift; exec 2>&1; eval "$command"',
1959+
"sh", $command) or
19171960
(fail "unable to exec $command" and return 0);
19181961

19191962
if (defined($opt{"LOG_FILE"})) {
@@ -2508,7 +2551,7 @@ sub check_buildlog {
25082551
my $save_no_reboot = $no_reboot;
25092552
$no_reboot = 1;
25102553

2511-
if (-f $warnings_file) {
2554+
if (defined($warnings_file) && -f $warnings_file) {
25122555
open(IN, $warnings_file) or
25132556
dodie "Error opening $warnings_file";
25142557

@@ -4183,15 +4226,17 @@ sub __set_test_option {
41834226

41844227
my $option = "$name\[$i\]";
41854228

4186-
if (option_defined($option)) {
4229+
if (exists($opt{$option})) {
4230+
return undef if (!option_defined($option));
41874231
return $opt{$option};
41884232
}
41894233

41904234
foreach my $test (keys %repeat_tests) {
41914235
if ($i >= $test &&
41924236
$i < $test + $repeat_tests{$test}) {
41934237
$option = "$name\[$test\]";
4194-
if (option_defined($option)) {
4238+
if (exists($opt{$option})) {
4239+
return undef if (!option_defined($option));
41954240
return $opt{$option};
41964241
}
41974242
}
@@ -4213,6 +4258,53 @@ sub set_test_option {
42134258
return eval_option($name, $option, $i);
42144259
}
42154260

4261+
sub print_test_preamble {
4262+
my ($resolved) = @_;
4263+
4264+
doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
4265+
4266+
for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
4267+
4268+
if (!$i) {
4269+
doprint "DEFAULT OPTIONS:\n";
4270+
} else {
4271+
doprint "\nTEST $i OPTIONS";
4272+
if (defined($repeat_tests{$i})) {
4273+
$repeat = $repeat_tests{$i};
4274+
doprint " ITERATE $repeat";
4275+
}
4276+
doprint "\n";
4277+
}
4278+
4279+
foreach my $option (sort keys %opt) {
4280+
my $value;
4281+
4282+
if ($option =~ /\[(\d+)\]$/) {
4283+
next if ($i != $1);
4284+
4285+
if ($resolved) {
4286+
my $name = $option;
4287+
$name =~ s/\[\d+\]$//;
4288+
$value = set_test_option($name, $i);
4289+
} else {
4290+
$value = $opt{$option};
4291+
}
4292+
} else {
4293+
next if ($i);
4294+
4295+
if ($resolved) {
4296+
$value = set_test_option($option, 0);
4297+
} else {
4298+
$value = $opt{$option};
4299+
}
4300+
}
4301+
4302+
$value = "" if (!defined($value));
4303+
doprint "$option = $value\n";
4304+
}
4305+
}
4306+
}
4307+
42164308
sub find_mailer {
42174309
my ($mailer) = @_;
42184310

@@ -4298,6 +4390,7 @@ sub cancel_test {
42984390
send_email("KTEST: Your [$name] test was cancelled",
42994391
"Your test started at $script_start_time was cancelled: sig int");
43004392
}
4393+
run_post_ktest;
43014394
die "\nCaught Sig Int, test interrupted: $!\n"
43024395
}
43034396

@@ -4311,6 +4404,8 @@ sub die_usage {
43114404
Sets global BUILD_NOCLEAN to 1
43124405
-D TEST_TYPE[2]=build
43134406
Sets TEST_TYPE of test 2 to "build"
4407+
--dry-run
4408+
Print resolved test options and exit without running tests.
43144409
43154410
It can also override all temp variables.
43164411
-D USE_TEMP_DIR:=1
@@ -4342,6 +4437,9 @@ sub die_usage {
43424437
} else {
43434438
$command_vars[$#command_vars + 1] = $val;
43444439
}
4440+
} elsif ( $ARGV[0] eq "--dry-run" ) {
4441+
$dry_run = 1;
4442+
shift;
43454443
} elsif ( $ARGV[0] eq "-h" ) {
43464444
die_usage;
43474445
} else {
@@ -4390,8 +4488,13 @@ sub die_usage {
43904488
}
43914489
read_config $ktest_config;
43924490

4491+
if ($dry_run) {
4492+
print_test_preamble 1;
4493+
exit 0;
4494+
}
4495+
43934496
if (defined($opt{"LOG_FILE"})) {
4394-
$opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1);
4497+
$opt{"LOG_FILE"} = set_test_option("LOG_FILE", 1);
43954498
}
43964499

43974500
# Append any configs entered in manually to the config file.
@@ -4421,31 +4524,7 @@ sub die_usage {
44214524
LOG->autoflush(1);
44224525
}
44234526

4424-
doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
4425-
4426-
for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
4427-
4428-
if (!$i) {
4429-
doprint "DEFAULT OPTIONS:\n";
4430-
} else {
4431-
doprint "\nTEST $i OPTIONS";
4432-
if (defined($repeat_tests{$i})) {
4433-
$repeat = $repeat_tests{$i};
4434-
doprint " ITERATE $repeat";
4435-
}
4436-
doprint "\n";
4437-
}
4438-
4439-
foreach my $option (sort keys %opt) {
4440-
if ($option =~ /\[(\d+)\]$/) {
4441-
next if ($i != $1);
4442-
} else {
4443-
next if ($i);
4444-
}
4445-
4446-
doprint "$option = $opt{$option}\n";
4447-
}
4448-
}
4527+
print_test_preamble 0;
44494528

44504529
$SIG{INT} = qw(cancel_test);
44514530

@@ -4492,7 +4571,11 @@ sub die_usage {
44924571
if ($i == 1) {
44934572
if (defined($pre_ktest)) {
44944573
doprint "\n";
4495-
run_command $pre_ktest;
4574+
my $ret = run_command $pre_ktest;
4575+
if (!$ret && defined($pre_ktest_die) &&
4576+
$pre_ktest_die) {
4577+
dodie "failed to pre_ktest\n";
4578+
}
44964579
}
44974580
if ($email_when_started) {
44984581
my $name = get_test_name;
@@ -4659,11 +4742,7 @@ sub die_usage {
46594742
success $i;
46604743
}
46614744

4662-
if (defined($final_post_ktest)) {
4663-
4664-
my $cp_final_post_ktest = eval_kernel_version $final_post_ktest;
4665-
run_command $cp_final_post_ktest;
4666-
}
4745+
run_post_ktest;
46674746

46684747
if ($opt{"POWEROFF_ON_SUCCESS"}) {
46694748
halt;

tools/testing/ktest/sample.conf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,12 @@
494494
#
495495
# default (undefined)
496496
#PRE_KTEST = ${SSH} ~/set_up_test
497+
#
498+
# To specify if the test should fail if PRE_KTEST fails,
499+
# PRE_KTEST_DIE needs to be set to 1. Otherwise the PRE_KTEST
500+
# result is ignored.
501+
# (default 0)
502+
#PRE_KTEST_DIE = 1
497503

498504
# If you want to execute some command after all the tests have
499505
# completed, you can set this option. Note, it can be set as a

0 commit comments

Comments
 (0)