forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/tools/testing/ktest/ktest.pl
....@@ -1,7 +1,7 @@
11 #!/usr/bin/perl -w
2
+# SPDX-License-Identifier: GPL-2.0-only
23 #
34 # Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4
-# Licensed under the terms of the GNU GPL License version 2
55 #
66
77 use strict;
....@@ -11,6 +11,7 @@
1111 use File::Copy qw(cp);
1212 use FileHandle;
1313 use FindBin;
14
+use IO::Handle;
1415
1516 my $VERSION = "0.2";
1617
....@@ -30,7 +31,7 @@
3031 "EMAIL_WHEN_STARTED" => 0,
3132 "NUM_TESTS" => 1,
3233 "TEST_TYPE" => "build",
33
- "BUILD_TYPE" => "randconfig",
34
+ "BUILD_TYPE" => "oldconfig",
3435 "MAKE_CMD" => "make",
3536 "CLOSE_CONSOLE_SIGNAL" => "INT",
3637 "TIMEOUT" => 120,
....@@ -58,11 +59,13 @@
5859 "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
5960 "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}",
6061 "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot",
62
+ "REBOOT_RETURN_CODE" => 255,
6163 "STOP_AFTER_SUCCESS" => 10,
6264 "STOP_AFTER_FAILURE" => 60,
6365 "STOP_TEST_AFTER" => 600,
6466 "MAX_MONITOR_WAIT" => 1800,
6567 "GRUB_REBOOT" => "grub2-reboot",
68
+ "GRUB_BLS_GET" => "grubby --info=ALL",
6669 "SYSLINUX" => "extlinux",
6770 "SYSLINUX_PATH" => "/boot/extlinux",
6871 "CONNECT_TIMEOUT" => 25,
....@@ -78,6 +81,8 @@
7881 "LOG_FILE" => undef,
7982 "IGNORE_UNUSED" => 0,
8083 );
84
+
85
+my $test_log_start = 0;
8186
8287 my $ktest_config = "ktest.conf";
8388 my $version;
....@@ -96,6 +101,7 @@
96101 my $pre_ktest;
97102 my $post_ktest;
98103 my $pre_test;
104
+my $pre_test_die;
99105 my $post_test;
100106 my $pre_build;
101107 my $post_build;
....@@ -105,6 +111,7 @@
105111 my $reboot_script;
106112 my $power_cycle;
107113 my $reboot;
114
+my $reboot_return_code;
108115 my $reboot_on_error;
109116 my $switch_to_good;
110117 my $switch_to_test;
....@@ -123,6 +130,7 @@
123130 my $grub_file;
124131 my $grub_number;
125132 my $grub_reboot;
133
+my $grub_bls_get;
126134 my $syslinux;
127135 my $syslinux_path;
128136 my $syslinux_label;
....@@ -219,6 +227,7 @@
219227 my $mailto;
220228 my $mailer;
221229 my $mail_path;
230
+my $mail_max_size;
222231 my $mail_command;
223232 my $email_on_error;
224233 my $email_when_finished;
....@@ -255,6 +264,7 @@
255264 "MAILTO" => \$mailto,
256265 "MAILER" => \$mailer,
257266 "MAIL_PATH" => \$mail_path,
267
+ "MAIL_MAX_SIZE" => \$mail_max_size,
258268 "MAIL_COMMAND" => \$mail_command,
259269 "EMAIL_ON_ERROR" => \$email_on_error,
260270 "EMAIL_WHEN_FINISHED" => \$email_when_finished,
....@@ -269,6 +279,7 @@
269279 "PRE_KTEST" => \$pre_ktest,
270280 "POST_KTEST" => \$post_ktest,
271281 "PRE_TEST" => \$pre_test,
282
+ "PRE_TEST_DIE" => \$pre_test_die,
272283 "POST_TEST" => \$post_test,
273284 "BUILD_TYPE" => \$build_type,
274285 "BUILD_OPTIONS" => \$build_options,
....@@ -278,6 +289,7 @@
278289 "POST_BUILD_DIE" => \$post_build_die,
279290 "POWER_CYCLE" => \$power_cycle,
280291 "REBOOT" => \$reboot,
292
+ "REBOOT_RETURN_CODE" => \$reboot_return_code,
281293 "BUILD_NOCLEAN" => \$noclean,
282294 "MIN_CONFIG" => \$minconfig,
283295 "OUTPUT_MIN_CONFIG" => \$output_minconfig,
....@@ -292,6 +304,7 @@
292304 "GRUB_MENU" => \$grub_menu,
293305 "GRUB_FILE" => \$grub_file,
294306 "GRUB_REBOOT" => \$grub_reboot,
307
+ "GRUB_BLS_GET" => \$grub_bls_get,
295308 "SYSLINUX" => \$syslinux,
296309 "SYSLINUX_PATH" => \$syslinux_path,
297310 "SYSLINUX_LABEL" => \$syslinux_label,
....@@ -437,7 +450,7 @@
437450 ;
438451 $config_help{"REBOOT_TYPE"} = << "EOF"
439452 Way to reboot the box to the test kernel.
440
- Only valid options so far are "grub", "grub2", "syslinux", and "script".
453
+ Only valid options so far are "grub", "grub2", "grub2bls", "syslinux", and "script".
441454
442455 If you specify grub, it will assume grub version 1
443456 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
....@@ -450,6 +463,8 @@
450463
451464 If you specify grub2, then you also need to specify both \$GRUB_MENU
452465 and \$GRUB_FILE.
466
+
467
+ If you specify grub2bls, then you also need to specify \$GRUB_MENU.
453468
454469 If you specify syslinux, then you may use SYSLINUX to define the syslinux
455470 command (defaults to extlinux), and SYSLINUX_PATH to specify the path to
....@@ -476,6 +491,9 @@
476491 menu must be a non-nested menu. Add the quotes used in the menu
477492 to guarantee your selection, as the first menuentry with the content
478493 of \$GRUB_MENU that is found will be used.
494
+
495
+ For grub2bls, \$GRUB_MENU is searched on the result of \$GRUB_BLS_GET
496
+ command for the lines that begin with "title".
479497 EOF
480498 ;
481499 $config_help{"GRUB_FILE"} = << "EOF"
....@@ -496,9 +514,7 @@
496514
497515 sub _logit {
498516 if (defined($opt{"LOG_FILE"})) {
499
- open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
500
- print OUT @_;
501
- close(OUT);
517
+ print LOG @_;
502518 }
503519 }
504520
....@@ -692,7 +708,7 @@
692708 }
693709 }
694710
695
- if ($rtype eq "grub") {
711
+ if (($rtype eq "grub") or ($rtype eq "grub2bls")) {
696712 get_mandatory_config("GRUB_MENU");
697713 }
698714
....@@ -898,6 +914,12 @@
898914 }
899915 }
900916
917
+ if ($val =~ s/^\s*NOT\s+(.*)//) {
918
+ my $express = $1;
919
+ my $ret = process_expression($name, $express);
920
+ return !$ret;
921
+ }
922
+
901923 if ($val =~ /^\s*0\s*$/) {
902924 return 0;
903925 } elsif ($val =~ /^\s*\d+\s*$/) {
....@@ -1019,7 +1041,7 @@
10191041 }
10201042
10211043 if (!$skip && $rest !~ /^\s*$/) {
1022
- die "$name: $.: Gargbage found after $type\n$_";
1044
+ die "$name: $.: Garbage found after $type\n$_";
10231045 }
10241046
10251047 if ($skip && $type eq "TEST_START") {
....@@ -1052,7 +1074,7 @@
10521074 }
10531075
10541076 if ($rest !~ /^\s*$/) {
1055
- die "$name: $.: Gargbage found after DEFAULTS\n$_";
1077
+ die "$name: $.: Garbage found after DEFAULTS\n$_";
10561078 }
10571079
10581080 } elsif (/^\s*INCLUDE\s+(\S+)/) {
....@@ -1143,7 +1165,7 @@
11431165 # on of these sections that have SKIP defined.
11441166 # The save variable can be
11451167 # defined multiple times and the new one simply overrides
1146
- # the prevous one.
1168
+ # the previous one.
11471169 set_variable($lvalue, $rvalue);
11481170
11491171 } else {
....@@ -1223,7 +1245,7 @@
12231245 foreach my $option (keys %not_used) {
12241246 print "$option\n";
12251247 }
1226
- print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
1248
+ print "Set IGNORE_UNUSED = 1 to have ktest ignore unused variables\n";
12271249 if (!read_yn "Do you want to continue?") {
12281250 exit -1;
12291251 }
....@@ -1334,7 +1356,7 @@
13341356 # Check for recursive evaluations.
13351357 # 100 deep should be more than enough.
13361358 if ($r++ > 100) {
1337
- die "Over 100 evaluations accurred with $option\n" .
1359
+ die "Over 100 evaluations occurred with $option\n" .
13381360 "Check for recursive variables\n";
13391361 }
13401362 $prev = $option;
....@@ -1437,15 +1459,26 @@
14371459
14381460 my $in_die = 0;
14391461
1462
+sub get_test_name() {
1463
+ my $name;
1464
+
1465
+ if (defined($test_name)) {
1466
+ $name = "$test_name:$test_type";
1467
+ } else {
1468
+ $name = $test_type;
1469
+ }
1470
+ return $name;
1471
+}
1472
+
14401473 sub dodie {
14411474
1442
- # avoid recusion
1475
+ # avoid recursion
14431476 return if ($in_die);
14441477 $in_die = 1;
14451478
1446
- doprint "CRITICAL FAILURE... ", @_, "\n";
1447
-
14481479 my $i = $iteration;
1480
+
1481
+ doprint "CRITICAL FAILURE... [TEST $i] ", @_, "\n";
14491482
14501483 if ($reboot_on_error && !do_not_reboot) {
14511484
....@@ -1462,8 +1495,32 @@
14621495 }
14631496
14641497 if ($email_on_error) {
1465
- send_email("KTEST: critical failure for your [$test_type] test",
1466
- "Your test started at $script_start_time has failed with:\n@_\n");
1498
+ my $name = get_test_name;
1499
+ my $log_file;
1500
+
1501
+ if (defined($opt{"LOG_FILE"})) {
1502
+ my $whence = 2; # End of file
1503
+ my $log_size = tell LOG;
1504
+ my $size = $log_size - $test_log_start;
1505
+
1506
+ if (defined($mail_max_size)) {
1507
+ if ($size > $mail_max_size) {
1508
+ $size = $mail_max_size;
1509
+ }
1510
+ }
1511
+ my $pos = - $size;
1512
+ $log_file = "$tmpdir/log";
1513
+ open (L, "$opt{LOG_FILE}") or die "Can't open $opt{LOG_FILE} to read)";
1514
+ open (O, "> $tmpdir/log") or die "Can't open $tmpdir/log\n";
1515
+ seek(L, $pos, $whence);
1516
+ while (<L>) {
1517
+ print O;
1518
+ }
1519
+ close O;
1520
+ close L;
1521
+ }
1522
+ send_email("KTEST: critical failure for test $i [$name]",
1523
+ "Your test started at $script_start_time has failed with:\n@_\n", $log_file);
14671524 }
14681525
14691526 if ($monitor_cnt) {
....@@ -1485,7 +1542,7 @@
14851542 my $TIOCGPTN = 0x80045430;
14861543
14871544 sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or
1488
- dodie "Cant open /dev/ptmx";
1545
+ dodie "Can't open /dev/ptmx";
14891546
14901547 # unlockpt()
14911548 $tmp = pack("i", 0);
....@@ -1737,6 +1794,7 @@
17371794 my $dord = 0;
17381795 my $dostdout = 0;
17391796 my $pid;
1797
+ my $command_orig = $command;
17401798
17411799 $command =~ s/\$SSH_USER/$ssh_user/g;
17421800 $command =~ s/\$MACHINE/$machine/g;
....@@ -1748,8 +1806,6 @@
17481806 (fail "unable to exec $command" and return 0);
17491807
17501808 if (defined($opt{"LOG_FILE"})) {
1751
- open(LOG, ">>$opt{LOG_FILE}") or
1752
- dodie "failed to write to log";
17531809 $dolog = 1;
17541810 }
17551811
....@@ -1791,8 +1847,12 @@
17911847 # shift 8 for real exit status
17921848 $run_command_status = $? >> 8;
17931849
1850
+ if ($command_orig eq $default{REBOOT} &&
1851
+ $run_command_status == $reboot_return_code) {
1852
+ $run_command_status = 0;
1853
+ }
1854
+
17941855 close(CMD);
1795
- close(LOG) if ($dolog);
17961856 close(RD) if ($dord);
17971857
17981858 $end_time = time;
....@@ -1850,35 +1910,37 @@
18501910 return run_scp($src, $dst, $cp_scp);
18511911 }
18521912
1853
-sub get_grub2_index {
1913
+sub _get_grub_index {
1914
+
1915
+ my ($command, $target, $skip) = @_;
18541916
18551917 return if (defined($grub_number) && defined($last_grub_menu) &&
18561918 $last_grub_menu eq $grub_menu && defined($last_machine) &&
18571919 $last_machine eq $machine);
18581920
1859
- doprint "Find grub2 menu ... ";
1921
+ doprint "Find $reboot_type menu ... ";
18601922 $grub_number = -1;
18611923
18621924 my $ssh_grub = $ssh_exec;
1863
- $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g;
1925
+ $ssh_grub =~ s,\$SSH_COMMAND,$command,g;
18641926
18651927 open(IN, "$ssh_grub |")
1866
- or dodie "unable to get $grub_file";
1928
+ or dodie "unable to execute $command";
18671929
18681930 my $found = 0;
18691931
18701932 while (<IN>) {
1871
- if (/^menuentry.*$grub_menu/) {
1933
+ if (/$target/) {
18721934 $grub_number++;
18731935 $found = 1;
18741936 last;
1875
- } elsif (/^menuentry\s|^submenu\s/) {
1937
+ } elsif (/$skip/) {
18761938 $grub_number++;
18771939 }
18781940 }
18791941 close(IN);
18801942
1881
- dodie "Could not find '$grub_menu' in $grub_file on $machine"
1943
+ dodie "Could not find '$grub_menu' through $command on $machine"
18821944 if (!$found);
18831945 doprint "$grub_number\n";
18841946 $last_grub_menu = $grub_menu;
....@@ -1887,45 +1949,34 @@
18871949
18881950 sub get_grub_index {
18891951
1890
- if ($reboot_type eq "grub2") {
1891
- get_grub2_index;
1952
+ my $command;
1953
+ my $target;
1954
+ my $skip;
1955
+ my $grub_menu_qt;
1956
+
1957
+ if ($reboot_type !~ /^grub/) {
18921958 return;
18931959 }
18941960
1895
- if ($reboot_type ne "grub") {
1961
+ $grub_menu_qt = quotemeta($grub_menu);
1962
+
1963
+ if ($reboot_type eq "grub") {
1964
+ $command = "cat /boot/grub/menu.lst";
1965
+ $target = '^\s*title\s+' . $grub_menu_qt . '\s*$';
1966
+ $skip = '^\s*title\s';
1967
+ } elsif ($reboot_type eq "grub2") {
1968
+ $command = "cat $grub_file";
1969
+ $target = '^menuentry.*' . $grub_menu_qt;
1970
+ $skip = '^menuentry\s|^submenu\s';
1971
+ } elsif ($reboot_type eq "grub2bls") {
1972
+ $command = $grub_bls_get;
1973
+ $target = '^title=.*' . $grub_menu_qt;
1974
+ $skip = '^title=';
1975
+ } else {
18961976 return;
18971977 }
1898
- return if (defined($grub_number) && defined($last_grub_menu) &&
1899
- $last_grub_menu eq $grub_menu && defined($last_machine) &&
1900
- $last_machine eq $machine);
19011978
1902
- doprint "Find grub menu ... ";
1903
- $grub_number = -1;
1904
-
1905
- my $ssh_grub = $ssh_exec;
1906
- $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1907
-
1908
- open(IN, "$ssh_grub |")
1909
- or dodie "unable to get menu.lst";
1910
-
1911
- my $found = 0;
1912
-
1913
- while (<IN>) {
1914
- if (/^\s*title\s+$grub_menu\s*$/) {
1915
- $grub_number++;
1916
- $found = 1;
1917
- last;
1918
- } elsif (/^\s*title\s/) {
1919
- $grub_number++;
1920
- }
1921
- }
1922
- close(IN);
1923
-
1924
- dodie "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1925
- if (!$found);
1926
- doprint "$grub_number\n";
1927
- $last_grub_menu = $grub_menu;
1928
- $last_machine = $machine;
1979
+ _get_grub_index($command, $target, $skip);
19291980 }
19301981
19311982 sub wait_for_input
....@@ -1988,7 +2039,7 @@
19882039
19892040 if ($reboot_type eq "grub") {
19902041 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1991
- } elsif ($reboot_type eq "grub2") {
2042
+ } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
19922043 run_ssh "$grub_reboot $grub_number";
19932044 } elsif ($reboot_type eq "syslinux") {
19942045 run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
....@@ -3168,6 +3219,8 @@
31683219 doprint "***************************************\n\n";
31693220 }
31703221
3222
+my $pass = 1;
3223
+
31713224 sub run_config_bisect {
31723225 my ($good, $bad, $last_result) = @_;
31733226 my $reset = "";
....@@ -3190,11 +3243,15 @@
31903243
31913244 $ret = run_config_bisect_test $config_bisect_type;
31923245 if ($ret) {
3193
- doprint "NEW GOOD CONFIG\n";
3246
+ doprint "NEW GOOD CONFIG ($pass)\n";
3247
+ system("cp $output_config $tmpdir/good_config.tmp.$pass");
3248
+ $pass++;
31943249 # Return 3 for good config
31953250 return 3;
31963251 } else {
3197
- doprint "NEW BAD CONFIG\n";
3252
+ doprint "NEW BAD CONFIG ($pass)\n";
3253
+ system("cp $output_config $tmpdir/bad_config.tmp.$pass");
3254
+ $pass++;
31983255 # Return 4 for bad config
31993256 return 4;
32003257 }
....@@ -4057,8 +4114,12 @@
40574114 }
40584115 }
40594116
4060
-if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
4061
- unlink $opt{"LOG_FILE"};
4117
+if (defined($opt{"LOG_FILE"})) {
4118
+ if ($opt{"CLEAR_LOG"}) {
4119
+ unlink $opt{"LOG_FILE"};
4120
+ }
4121
+ open(LOG, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
4122
+ LOG->autoflush(1);
40624123 }
40634124
40644125 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
....@@ -4151,7 +4212,7 @@
41514212 }
41524213
41534214 sub do_send_mail {
4154
- my ($subject, $message) = @_;
4215
+ my ($subject, $message, $file) = @_;
41554216
41564217 if (!defined($mail_path)) {
41574218 # find the mailer
....@@ -4161,16 +4222,30 @@
41614222 }
41624223 }
41634224
4225
+ my $header_file = "$tmpdir/header";
4226
+ open (HEAD, ">$header_file") or die "Can not create $header_file\n";
4227
+ print HEAD "To: $mailto\n";
4228
+ print HEAD "Subject: $subject\n\n";
4229
+ print HEAD "$message\n";
4230
+ close HEAD;
4231
+
41644232 if (!defined($mail_command)) {
41654233 if ($mailer eq "mail" || $mailer eq "mailx") {
4166
- $mail_command = "\$MAIL_PATH/\$MAILER -s \'\$SUBJECT\' \$MAILTO <<< \'\$MESSAGE\'";
4234
+ $mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -s \'\$SUBJECT\' \$MAILTO";
41674235 } elsif ($mailer eq "sendmail" ) {
4168
- $mail_command = "echo \'Subject: \$SUBJECT\n\n\$MESSAGE\' | \$MAIL_PATH/\$MAILER -t \$MAILTO";
4236
+ $mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -t \$MAILTO";
41694237 } else {
41704238 die "\nYour mailer: $mailer is not supported.\n";
41714239 }
41724240 }
41734241
4242
+ if (defined($file)) {
4243
+ $mail_command =~ s/\$BODY_FILE/$file/g;
4244
+ } else {
4245
+ $mail_command =~ s/\$BODY_FILE//g;
4246
+ }
4247
+
4248
+ $mail_command =~ s/\$HEADER_FILE/$header_file/g;
41744249 $mail_command =~ s/\$MAILER/$mailer/g;
41754250 $mail_command =~ s/\$MAIL_PATH/$mail_path/g;
41764251 $mail_command =~ s/\$MAILTO/$mailto/g;
....@@ -4198,7 +4273,8 @@
41984273
41994274 sub cancel_test {
42004275 if ($email_when_canceled) {
4201
- send_email("KTEST: Your [$test_type] test was cancelled",
4276
+ my $name = get_test_name;
4277
+ send_email("KTEST: Your [$name] test was cancelled",
42024278 "Your test started at $script_start_time was cancelled: sig int");
42034279 }
42044280 die "\nCaught Sig Int, test interrupted: $!\n"
....@@ -4252,7 +4328,8 @@
42524328 run_command $pre_ktest;
42534329 }
42544330 if ($email_when_started) {
4255
- send_email("KTEST: Your [$test_type] test was started",
4331
+ my $name = get_test_name;
4332
+ send_email("KTEST: Your [$name] test was started",
42564333 "Your test was started on $script_start_time");
42574334 }
42584335 }
....@@ -4283,7 +4360,7 @@
42834360
42844361 if (!$buildonly) {
42854362 $target = "$ssh_user\@$machine";
4286
- if ($reboot_type eq "grub") {
4363
+ if (($reboot_type eq "grub") or ($reboot_type eq "grub2bls")) {
42874364 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
42884365 } elsif ($reboot_type eq "grub2") {
42894366 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
....@@ -4321,10 +4398,19 @@
43214398 }
43224399
43234400 doprint "\n\n";
4401
+
4402
+ if (defined($opt{"LOG_FILE"})) {
4403
+ $test_log_start = tell(LOG);
4404
+ }
4405
+
43244406 doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n";
43254407
43264408 if (defined($pre_test)) {
4327
- run_command $pre_test;
4409
+ my $ret = run_command $pre_test;
4410
+ if (!$ret && defined($pre_test_die) &&
4411
+ $pre_test_die) {
4412
+ dodie "failed to pre_test\n";
4413
+ }
43284414 }
43294415
43304416 unlink $dmesg;
....@@ -4403,7 +4489,9 @@
44034489 }
44044490
44054491 if (defined($final_post_ktest)) {
4406
- run_command $final_post_ktest;
4492
+
4493
+ my $cp_final_post_ktest = eval_kernel_version $final_post_ktest;
4494
+ run_command $cp_final_post_ktest;
44074495 }
44084496
44094497 if ($opt{"POWEROFF_ON_SUCCESS"}) {
....@@ -4419,7 +4507,13 @@
44194507 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
44204508
44214509 if ($email_when_finished) {
4422
- send_email("KTEST: Your [$test_type] test has finished!",
4510
+ send_email("KTEST: Your test has finished!",
44234511 "$successes of $opt{NUM_TESTS} tests started at $script_start_time were successful!");
44244512 }
4513
+
4514
+if (defined($opt{"LOG_FILE"})) {
4515
+ print "\n See $opt{LOG_FILE} for the record of results.\n\n";
4516
+ close LOG;
4517
+}
4518
+
44254519 exit 0;