2 #***************************************************************************
4 # Project ___| | | | _ \| |
6 # | (__| |_| | _ <| |___
7 # \___|\___/|_| \_\_____|
9 # Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
11 # This software is licensed as described in the file COPYING, which
12 # you should have received as part of this distribution. The terms
13 # are also available at http://curl.haxx.se/docs/copyright.html.
15 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
16 # copies of the Software, and permit persons to whom the Software is
17 # furnished to do so, under the terms of the COPYING file.
19 # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 # KIND, either express or implied.
22 ###########################################################################
24 # Experimental hooks are available to run tests remotely on machines that
25 # are able to run curl but are unable to run the test harness.
26 # The following sections need to be modified:
28 # $HOSTIP, $HOST6IP - Set to the address of the host running the test suite
29 # $CLIENTIP, $CLIENT6IP - Set to the address of the host running curl
30 # runclient, runclientoutput - Modify to copy all the files in the log/
31 # directory to the system running curl, run the given command remotely
32 # and save the return code or returned stdout (respectively), then
33 # copy all the files from the remote system's log/ directory back to
34 # the host running the test suite. This can be done a few ways, such
35 # as using scp & ssh, rsync & telnet, or using a NFS shared directory
38 # 'make && make test' needs to be done on both machines before making the
39 # above changes and running runtests.pl manually. In the shared NFS case,
40 # the contents of the tests/server/ directory must be from the host
41 # running the test suite, while the rest must be from the host running curl.
43 # Note that even with these changes a number of tests will still fail (mainly
44 # to do with cookies, those that set environment variables, or those that
45 # do more than touch the file system in a <precheck> or <postcheck>
46 # section). These can be added to the $TESTCASES line below,
47 # e.g. $TESTCASES="!8 !31 !63 !cookies..."
49 # Finally, to properly support -g and -n, checktestcmd needs to change
50 # to check the remote system's PATH, and the places in the code where
51 # the curl binary is read directly to determine its type also need to be
52 # fixed. As long as the -g option is never given, and the -n is always
53 # given, this won't be a problem.
56 # These should be the only variables that might be needed to get edited:
59 @INC=(@INC, $ENV{'srcdir'}, ".");
60 # run time statistics needs Time::HiRes
64 import Time::HiRes qw( time );
72 # Subs imported from serverhelp module
82 # Variables and subs imported from sshhelp module
107 require "getpart.pm"; # array functions
108 require "valgrind.pm"; # valgrind report parser
111 my $HOSTIP="127.0.0.1"; # address on which the test server listens
112 my $HOST6IP="[::1]"; # address on which the test server listens
113 my $CLIENTIP="127.0.0.1"; # address which curl uses for incoming connections
114 my $CLIENT6IP="[::1]"; # address which curl uses for incoming connections
116 my $base = 8990; # base port number
118 my $HTTPPORT; # HTTP server port
119 my $HTTP6PORT; # HTTP IPv6 server port
120 my $HTTPSPORT; # HTTPS (stunnel) server port
121 my $FTPPORT; # FTP server port
122 my $FTP2PORT; # FTP server 2 port
123 my $FTPSPORT; # FTPS (stunnel) server port
124 my $FTP6PORT; # FTP IPv6 server port
126 my $TFTP6PORT; # TFTP
127 my $SSHPORT; # SCP/SFTP
128 my $SOCKSPORT; # SOCKS4/5 port
130 my $POP36PORT; # POP3 IPv6 server port
132 my $IMAP6PORT; # IMAP IPv6 server port
134 my $SMTP6PORT; # SMTP IPv6 server port
136 my $RTSP6PORT; # RTSP IPv6 server port
137 my $GOPHERPORT; # Gopher
138 my $GOPHER6PORT; # Gopher IPv6 server port
139 my $HTTPTLSPORT; # HTTP TLS (non-stunnel) server port
140 my $HTTPTLS6PORT; # HTTP TLS (non-stunnel) IPv6 server port
142 my $srcdir = $ENV{'srcdir'} || '.';
143 my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
144 my $VCURL=$CURL; # what curl binary to use to verify the servers with
145 # VCURL is handy to set to the system one when the one you
146 # just built hangs or crashes and thus prevent verification
147 my $DBGCURL=$CURL; #"../src/.libs/curl"; # alternative for debugging
149 my $TESTDIR="$srcdir/data";
150 my $LIBDIR="./libtest";
151 my $UNITDIR="./unit";
152 my $SERVERIN="$LOGDIR/server.input"; # what curl sent the server
153 my $SERVER2IN="$LOGDIR/server2.input"; # what curl sent the second server
154 my $CURLLOG="$LOGDIR/curl.log"; # all command lines run
155 my $FTPDCMD="$LOGDIR/ftpserver.cmd"; # copy ftp server instructions here
156 my $SERVERLOGS_LOCK="$LOGDIR/serverlogs.lock"; # server logs advisor read lock
157 my $CURLCONFIG="../curl-config"; # curl-config from current build
159 # Normally, all test cases should be run, but at times it is handy to
160 # simply run a particular one:
163 # To run specific test cases, set them like:
164 # $TESTCASES="1 2 3 7 8";
166 #######################################################################
167 # No variables below this point should need to be modified
170 # invoke perl like this:
171 my $perl="perl -I$srcdir";
172 my $server_response_maxtime=13;
174 my $debug_build=0; # curl built with --enable-debug
175 my $curl_debug=0; # curl built with --enable-curldebug (memory tracking)
178 # name of the file that the memory debugging creates:
179 my $memdump="$LOGDIR/memdump";
181 # the path to the script that analyzes the memory debug output file:
182 my $memanalyze="$perl $srcdir/memanalyze.pl";
184 my $pwd = getcwd(); # current working directory
188 my $ftpchecktime=1; # time it took to verify our test FTP server
190 my $stunnel = checkcmd("stunnel4") || checkcmd("stunnel");
191 my $valgrind = checktestcmd("valgrind");
192 my $valgrind_logfile="--logfile";
194 my $gdb = checktestcmd("gdb");
195 my $httptlssrv = find_httptlssrv();
197 my $ssl_version; # set if libcurl is built with SSL support
198 my $large_file; # set if libcurl is built with large file support
199 my $has_idn; # set if libcurl is built with IDN support
200 my $http_ipv6; # set if HTTP server has IPv6 support
201 my $ftp_ipv6; # set if FTP server has IPv6 support
202 my $tftp_ipv6; # set if TFTP server has IPv6 support
203 my $gopher_ipv6; # set if Gopher server has IPv6 support
204 my $has_ipv6; # set if libcurl is built with IPv6 support
205 my $has_libz; # set if libcurl is built with libz support
206 my $has_getrlimit; # set if system has getrlimit()
207 my $has_ntlm; # set if libcurl is built with NTLM support
208 my $has_ntlm_wb; # set if libcurl is built with NTLM delegation to winbind
209 my $has_charconv;# set if libcurl is built with CharConv support
210 my $has_tls_srp; # set if libcurl is built with TLS-SRP support
212 my $has_openssl; # built with a lib using an OpenSSL-like API
213 my $has_gnutls; # built with GnuTLS
214 my $has_nss; # built with NSS
215 my $has_yassl; # built with yassl
216 my $has_polarssl;# built with polarssl
217 my $has_axtls; # built with axTLS
219 my $has_shared; # built shared
221 my $ssllib; # name of the lib we use (for human presentation)
222 my $has_crypto; # set if libcurl is built with cryptographic support
223 my $has_textaware; # set if running on a system that has a text mode concept
224 # on files. Windows for example
226 my @protocols; # array of lowercase supported protocol servers
228 my $skipped=0; # number of tests skipped; reported in main loop
229 my %skipped; # skipped{reason}=counter, reasons for skip
230 my @teststat; # teststat[testnum]=reason, reasons for skip
231 my %disabled_keywords; # key words of tests to skip
232 my %enabled_keywords; # key words of tests to run
233 my %disabled; # disabled test cases
235 my $sshdid; # for socks server, ssh daemon version id
236 my $sshdvernum; # for socks server, ssh daemon version number
237 my $sshdverstr; # for socks server, ssh daemon version string
238 my $sshderror; # for socks server, ssh daemon version error
240 my $defserverlogslocktimeout = 20; # timeout to await server logs lock removal
241 my $defpostcommanddelay = 0; # delay between command and postcheck sections
243 my $timestats; # time stamping and stats generation
244 my $fullstats; # show time stats for every single test
245 my %timeprepini; # timestamp for each test preparation start
246 my %timesrvrini; # timestamp for each test required servers verification start
247 my %timesrvrend; # timestamp for each test required servers verification end
248 my %timetoolini; # timestamp for each test command run starting
249 my %timetoolend; # timestamp for each test command run stopping
250 my %timesrvrlog; # timestamp for each test server logs lock removal
251 my %timevrfyend; # timestamp for each test result verification end
253 my $testnumcheck; # test number, set in singletest sub.
256 #######################################################################
257 # variables the command line options may set
264 my $gdbthis; # run test case with gdb debugger
265 my $gdbxwin; # use windowed gdb when using gdb
266 my $keepoutfiles; # keep stdout and stderr files after tests
267 my $listonly; # only list the tests
268 my $postmortem; # display detailed info about failed tests
270 my %run; # running server
271 my %doesntrun; # servers that don't work, identified by pidfile
272 my %serverpidfile;# all server pid file names, identified by server id
273 my %runcert; # cert file currently in use by an ssl running server
275 # torture test variables
280 #######################################################################
281 # logmsg is our general message logging subroutine.
289 # get the name of the current user
290 my $USER = $ENV{USER}; # Linux
292 $USER = $ENV{USERNAME}; # Windows
294 $USER = $ENV{LOGNAME}; # Some UNIX (I think)
298 # enable memory debugging if curl is compiled with it
299 $ENV{'CURL_MEMDEBUG'} = $memdump;
304 logmsg "runtests.pl received SIG$signame, exiting\n";
305 stopservers($verbose);
306 die "Somebody sent me a SIG$signame";
308 $SIG{INT} = \&catch_zap;
309 $SIG{TERM} = \&catch_zap;
311 ##########################################################################
312 # Clear all possible '*_proxy' environment variables for various protocols
313 # to prevent them to interfere with our testing!
316 foreach $protocol (('ftp', 'http', 'ftps', 'https', 'no', 'all')) {
317 my $proxy = "${protocol}_proxy";
318 # clear lowercase version
319 delete $ENV{$proxy} if($ENV{$proxy});
320 # clear uppercase version
321 delete $ENV{uc($proxy)} if($ENV{uc($proxy)});
324 # make sure we don't get affected by other variables that control our
327 delete $ENV{'SSL_CERT_DIR'} if($ENV{'SSL_CERT_DIR'});
328 delete $ENV{'SSL_CERT_PATH'} if($ENV{'SSL_CERT_PATH'});
329 delete $ENV{'CURL_CA_BUNDLE'} if($ENV{'CURL_CA_BUNDLE'});
331 #######################################################################
332 # Load serverpidfile hash with pidfile names for all possible servers.
334 sub init_serverpidfile_hash {
335 for my $proto (('ftp', 'http', 'imap', 'pop3', 'smtp')) {
336 for my $ssl (('', 's')) {
337 for my $ipvnum ((4, 6)) {
338 for my $idnum ((1, 2)) {
339 my $serv = servername_id("$proto$ssl", $ipvnum, $idnum);
340 my $pidf = server_pidfilename("$proto$ssl", $ipvnum, $idnum);
341 $serverpidfile{$serv} = $pidf;
346 for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp', 'gopher', 'httptls')) {
347 for my $ipvnum ((4, 6)) {
348 for my $idnum ((1, 2)) {
349 my $serv = servername_id($proto, $ipvnum, $idnum);
350 my $pidf = server_pidfilename($proto, $ipvnum, $idnum);
351 $serverpidfile{$serv} = $pidf;
357 #######################################################################
358 # Check if a given child process has just died. Reaps it if so.
361 use POSIX ":sys_wait_h";
363 if(not defined $pid || $pid <= 0) {
366 my $rc = waitpid($pid, &WNOHANG);
367 return ($rc == $pid)?1:0;
370 #######################################################################
371 # Start a new thread/process and run the given command line in there.
372 # Return the pids (yes plural) of the new child process to the parent.
375 my ($cmd, $pidfile, $timeout, $fake)=@_;
377 logmsg "startnew: $cmd\n" if ($verbose);
382 if(not defined $child) {
383 logmsg "startnew: fork() failure detected\n";
388 # Here we are the child. Run the given command.
390 # Put an "exec" in front of the command so that the child process
391 # keeps this child's process ID.
392 exec("exec $cmd") || die "Can't exec() $cmd: $!";
394 # exec() should never return back here to this process. We protect
395 # ourselves by calling die() just in case something goes really bad.
396 die "error: exec() has returned";
399 # Ugly hack but ssh client and gnutls-serv don't support pid files
401 if(open(OUT, ">$pidfile")) {
402 print OUT $child . "\n";
404 logmsg "startnew: $pidfile faked with pid=$child\n" if($verbose);
407 logmsg "startnew: failed to write fake $pidfile with pid=$child\n";
409 # could/should do a while connect fails sleep a bit and loop
411 if (checkdied($child)) {
412 logmsg "startnew: child process has failed to start\n" if($verbose);
417 my $count = $timeout;
419 if(-f $pidfile && -s $pidfile && open(PID, "<$pidfile")) {
422 if(($pid2 > 0) && kill(0, $pid2)) {
423 # if $pid2 is valid, then make sure this pid is alive, as
424 # otherwise it is just likely to be the _previous_ pidfile or
428 # invalidate $pid2 if not actually alive
431 if (checkdied($child)) {
432 logmsg "startnew: child process has died, server might start up\n"
434 # We can't just abort waiting for the server with a
436 # because the server might have forked and could still start
437 # up normally. Instead, just reduce the amount of time we remain
444 # Return two PIDs, the one for the child process we spawned and the one
445 # reported by the server itself (in case it forked again on its own).
446 # Both (potentially) need to be killed at the end of the test.
447 return ($child, $pid2);
451 #######################################################################
452 # Check for a command in the PATH of the test server.
456 my @paths=(split(":", $ENV{'PATH'}), "/usr/sbin", "/usr/local/sbin",
457 "/sbin", "/usr/bin", "/usr/local/bin",
458 "./libtest/.libs", "./libtest");
460 if( -x "$_/$cmd" && ! -d "$_/$cmd") {
461 # executable bit but not a directory!
467 #######################################################################
468 # Get the list of tests that the tests/data/Makefile.am knows about!
472 my @dist = `cd data && make show`;
473 $disttests = join("", @dist);
476 #######################################################################
477 # Check for a command in the PATH of the machine running curl.
481 return checkcmd($cmd);
484 #######################################################################
485 # Run the application under test and return its return code
491 # This is one way to test curl on a remote machine
492 # my $out = system("ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'");
493 # sleep 2; # time to allow the NFS server to be updated
497 #######################################################################
498 # Run the application under test and return its stdout
500 sub runclientoutput {
504 # This is one way to test curl on a remote machine
505 # my @out = `ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'`;
506 # sleep 2; # time to allow the NFS server to be updated
510 #######################################################################
511 # Memory allocation test and failure torture testing.
517 # remove memdump first to be sure we get a new nice and clean one
520 # First get URL from test server, ignore the output/result
523 logmsg " CMD: $testcmd\n" if($verbose);
525 # memanalyze -v is our friend, get the number of allocations made
527 my @out = `$memanalyze -v $memdump`;
529 if(/^Allocations: (\d+)/) {
535 logmsg " found no allocs to make fail\n";
539 logmsg " $count allocations to make fail\n";
541 for ( 1 .. $count ) {
546 if($tortalloc && ($tortalloc != $limit)) {
551 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
553 my $now = sprintf("%02d:%02d:%02d ", $hour, $min, $sec);
554 logmsg "Fail alloc no: $limit at $now\r";
557 # make the memory allocation function number $limit return failure
558 $ENV{'CURL_MEMLIMIT'} = $limit;
560 # remove memdump first to be sure we get a new nice and clean one
563 logmsg "*** Alloc number $limit is now set to fail ***\n" if($gdbthis);
570 $ret = runclient($testcmd);
572 #logmsg "$_ Returned " . $ret >> 8 . "\n";
574 # Now clear the variable again
575 delete $ENV{'CURL_MEMLIMIT'} if($ENV{'CURL_MEMLIMIT'});
578 # there's core file present now!
579 logmsg " core dumped\n";
584 # verify that it returns a proper error code, doesn't leak memory
585 # and doesn't core dump
587 logmsg " system() returned $ret\n";
591 my @memdata=`$memanalyze $memdump`;
595 # well it could be other memory problems as well, but
596 # we call it leak for short here
601 logmsg "** MEMORY FAILURE\n";
603 logmsg `$memanalyze -l $memdump`;
608 logmsg " Failed on alloc number $limit in test.\n",
609 " invoke with \"-t$limit\" to repeat this single case.\n";
610 stopservers($verbose);
615 logmsg "torture OK\n";
619 #######################################################################
620 # Stop a test server along with pids which aren't in the %run hash yet.
621 # This also stops all servers which are relative to the given one.
624 my ($server, $pidlist) = @_;
626 # kill sockfilter processes for pingpong relative server
628 if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
630 my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
631 my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
632 killsockfilters($proto, $ipvnum, $idnum, $verbose);
635 # All servers relative to the given one must be stopped also
638 if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
639 # given a stunnel based ssl server, also kill non-ssl underlying one
640 push @killservers, "${1}${2}";
642 elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|))$/) {
643 # given a non-ssl server, also kill stunnel based ssl piggybacking one
644 push @killservers, "${1}s${2}";
646 elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
647 # given a socks server, also kill ssh underlying one
648 push @killservers, "ssh${2}";
650 elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
651 # given a ssh server, also kill socks piggybacking one
652 push @killservers, "socks${2}";
654 push @killservers, $server;
656 # kill given pids and server relative ones clearing them in %run hash
658 foreach my $server (@killservers) {
660 # we must prepend a space since $pidlist may already contain a pid
661 $pidlist .= " $run{$server}";
664 $runcert{$server} = 0 if($runcert{$server});
666 killpid($verbose, $pidlist);
668 # cleanup server pid files
670 foreach my $server (@killservers) {
671 my $pidfile = $serverpidfile{$server};
672 my $pid = processexists($pidfile);
674 logmsg "Warning: $server server unexpectedly alive\n";
675 killpid($verbose, $pid);
677 unlink($pidfile) if(-f $pidfile);
681 #######################################################################
682 # Verify that the server that runs on $ip, $port is our server. This also
683 # implies that we can speak with it, as there might be occasions when the
684 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
685 # assign requested address")
688 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
689 my $server = servername_id($proto, $ipvnum, $idnum);
693 my $verifyout = "$LOGDIR/".
694 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
695 unlink($verifyout) if(-f $verifyout);
697 my $verifylog = "$LOGDIR/".
698 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
699 unlink($verifylog) if(-f $verifylog);
701 if($proto eq "gopher") {
706 my $flags = "--max-time $server_response_maxtime ";
707 $flags .= "--output $verifyout ";
708 $flags .= "--silent ";
709 $flags .= "--verbose ";
710 $flags .= "--globoff ";
711 $flags .= "-1 " if($has_axtls);
712 $flags .= "--insecure " if($proto eq 'https');
713 $flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\"";
715 my $cmd = "$VCURL $flags 2>$verifylog";
717 # verify if our/any server is running on this port
718 logmsg "RUN: $cmd\n" if($verbose);
719 my $res = runclient($cmd);
721 $res >>= 8; # rotate the result
723 logmsg "RUN: curl command died with a coredump\n";
727 if($res && $verbose) {
728 logmsg "RUN: curl command returned $res\n";
729 if(open(FILE, "<$verifylog")) {
730 while(my $string = <FILE>) {
731 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
738 if(open(FILE, "<$verifyout")) {
739 while(my $string = <FILE>) {
741 last; # only want first line
746 if($data && ($data =~ /WE ROOLZ: (\d+)/)) {
750 # curl: (6) Couldn't resolve host '::1'
751 logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
754 elsif($data || ($res && ($res != 7))) {
755 logmsg "RUN: Unknown server on our $server port: $port ($res)\n";
761 #######################################################################
762 # Verify that the server that runs on $ip, $port is our server. This also
763 # implies that we can speak with it, as there might be occasions when the
764 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
765 # assign requested address")
768 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
769 my $server = servername_id($proto, $ipvnum, $idnum);
774 my $verifylog = "$LOGDIR/".
775 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
776 unlink($verifylog) if(-f $verifylog);
778 if($proto eq "ftps") {
779 $extra .= "--insecure --ftp-ssl-control ";
781 elsif($proto eq "smtp") {
782 # SMTP is a bit different since it requires more options and it
784 $extra .= "--mail-rcpt verifiedserver ";
785 $extra .= "--mail-from fake ";
786 $extra .= "--upload /dev/null ";
787 $extra .= "--stderr - "; # move stderr to parse the verbose stuff
790 my $flags = "--max-time $server_response_maxtime ";
791 $flags .= "--silent ";
792 $flags .= "--verbose ";
793 $flags .= "--globoff ";
795 $flags .= "\"$proto://$ip:$port/verifiedserver\"";
797 my $cmd = "$VCURL $flags 2>$verifylog";
799 # check if this is our server running on this port:
800 logmsg "RUN: $cmd\n" if($verbose);
801 my @data = runclientoutput($cmd);
803 my $res = $? >> 8; # rotate the result
805 logmsg "RUN: curl command died with a coredump\n";
809 foreach my $line (@data) {
810 if($line =~ /WE ROOLZ: (\d+)/) {
811 # this is our test server with a known pid!
816 if($pid <= 0 && @data && $data[0]) {
817 # this is not a known server
818 logmsg "RUN: Unknown server on our $server port: $port\n";
821 # we can/should use the time it took to verify the FTP server as a measure
822 # on how fast/slow this host/FTP is.
823 my $took = int(0.5+time()-$time);
826 logmsg "RUN: Verifying our test $server server took $took seconds\n";
828 $ftpchecktime = $took>=1?$took:1; # make sure it never is below 1
833 #######################################################################
834 # Verify that the server that runs on $ip, $port is our server. This also
835 # implies that we can speak with it, as there might be occasions when the
836 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
837 # assign requested address")
840 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
841 my $server = servername_id($proto, $ipvnum, $idnum);
844 my $verifyout = "$LOGDIR/".
845 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
846 unlink($verifyout) if(-f $verifyout);
848 my $verifylog = "$LOGDIR/".
849 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
850 unlink($verifylog) if(-f $verifylog);
852 my $flags = "--max-time $server_response_maxtime ";
853 $flags .= "--output $verifyout ";
854 $flags .= "--silent ";
855 $flags .= "--verbose ";
856 $flags .= "--globoff ";
857 # currently verification is done using http
858 $flags .= "\"http://$ip:$port/verifiedserver\"";
860 my $cmd = "$VCURL $flags 2>$verifylog";
862 # verify if our/any server is running on this port
863 logmsg "RUN: $cmd\n" if($verbose);
864 my $res = runclient($cmd);
866 $res >>= 8; # rotate the result
868 logmsg "RUN: curl command died with a coredump\n";
872 if($res && $verbose) {
873 logmsg "RUN: curl command returned $res\n";
874 if(open(FILE, "<$verifylog")) {
875 while(my $string = <FILE>) {
876 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
883 if(open(FILE, "<$verifyout")) {
884 while(my $string = <FILE>) {
886 last; # only want first line
891 if($data && ($data =~ /RTSP_SERVER WE ROOLZ: (\d+)/)) {
895 # curl: (6) Couldn't resolve host '::1'
896 logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
899 elsif($data || ($res != 7)) {
900 logmsg "RUN: Unknown server on our $server port: $port\n";
906 #######################################################################
907 # Verify that the ssh server has written out its pidfile, recovering
908 # the pid from the file and returning it if a process with that pid is
912 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
913 my $server = servername_id($proto, $ipvnum, $idnum);
914 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
916 if(open(FILE, "<$pidfile")) {
921 # if we have a pid it is actually our ssh server,
922 # since runsshserver() unlinks previous pidfile
924 logmsg "RUN: SSH server has died after starting up\n";
933 #######################################################################
934 # Verify that we can connect to the sftp server, properly authenticate
935 # with generated config and key files and run a simple remote pwd.
938 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
939 my $server = servername_id($proto, $ipvnum, $idnum);
941 # Find out sftp client canonical file name
942 my $sftp = find_sftp();
944 logmsg "RUN: SFTP server cannot find $sftpexe\n";
947 # Find out ssh client canonical file name
948 my $ssh = find_ssh();
950 logmsg "RUN: SFTP server cannot find $sshexe\n";
953 # Connect to sftp server, authenticate and run a remote pwd
954 # command using our generated configuration and key files
955 my $cmd = "$sftp -b $sftpcmds -F $sftpconfig -S $ssh $ip > $sftplog 2>&1";
956 my $res = runclient($cmd);
957 # Search for pwd command response in log file
958 if(open(SFTPLOGFILE, "<$sftplog")) {
959 while(<SFTPLOGFILE>) {
960 if(/^Remote working directory: /) {
970 #######################################################################
971 # Verify that the non-stunnel HTTP TLS extensions capable server that runs
972 # on $ip, $port is our server. This also implies that we can speak with it,
973 # as there might be occasions when the server runs fine but we cannot talk
974 # to it ("Failed to connect to ::1: Can't assign requested address")
977 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
978 my $server = servername_id($proto, $ipvnum, $idnum);
979 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
982 my $verifyout = "$LOGDIR/".
983 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
984 unlink($verifyout) if(-f $verifyout);
986 my $verifylog = "$LOGDIR/".
987 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
988 unlink($verifylog) if(-f $verifylog);
990 my $flags = "--max-time $server_response_maxtime ";
991 $flags .= "--output $verifyout ";
992 $flags .= "--verbose ";
993 $flags .= "--globoff ";
994 $flags .= "--insecure ";
995 $flags .= "--tlsauthtype SRP ";
996 $flags .= "--tlsuser jsmith ";
997 $flags .= "--tlspassword abc ";
998 $flags .= "\"https://$ip:$port/verifiedserver\"";
1000 my $cmd = "$VCURL $flags 2>$verifylog";
1002 # verify if our/any server is running on this port
1003 logmsg "RUN: $cmd\n" if($verbose);
1004 my $res = runclient($cmd);
1006 $res >>= 8; # rotate the result
1008 logmsg "RUN: curl command died with a coredump\n";
1012 if($res && $verbose) {
1013 logmsg "RUN: curl command returned $res\n";
1014 if(open(FILE, "<$verifylog")) {
1015 while(my $string = <FILE>) {
1016 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
1023 if(open(FILE, "<$verifyout")) {
1024 while(my $string = <FILE>) {
1030 if($data && ($data =~ /GNUTLS/) && open(FILE, "<$pidfile")) {
1034 # if we have a pid it is actually our httptls server,
1035 # since runhttptlsserver() unlinks previous pidfile
1036 if(!kill(0, $pid)) {
1037 logmsg "RUN: $server server has died after starting up\n";
1046 # curl: (6) Couldn't resolve host '::1'
1047 logmsg "RUN: failed to resolve host (https://$ip:$port/verifiedserver)\n";
1050 elsif($data || ($res && ($res != 7))) {
1051 logmsg "RUN: Unknown server on our $server port: $port ($res)\n";
1057 #######################################################################
1058 # STUB for verifying socks
1061 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1062 my $server = servername_id($proto, $ipvnum, $idnum);
1063 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
1065 if(open(FILE, "<$pidfile")) {
1070 # if we have a pid it is actually our socks server,
1071 # since runsocksserver() unlinks previous pidfile
1072 if(!kill(0, $pid)) {
1073 logmsg "RUN: SOCKS server has died after starting up\n";
1082 #######################################################################
1083 # Verify that the server that runs on $ip, $port is our server.
1084 # Retry over several seconds before giving up. The ssh server in
1085 # particular can take a long time to start if it needs to generate
1086 # keys on a slow or loaded host.
1088 # Just for convenience, test harness uses 'https' and 'httptls' literals
1089 # as values for 'proto' variable in order to differentiate different
1090 # servers. 'https' literal is used for stunnel based https test servers,
1091 # and 'httptls' is used for non-stunnel https test servers.
1094 my %protofunc = ('http' => \&verifyhttp,
1095 'https' => \&verifyhttp,
1096 'rtsp' => \&verifyrtsp,
1097 'ftp' => \&verifyftp,
1098 'pop3' => \&verifyftp,
1099 'imap' => \&verifyftp,
1100 'smtp' => \&verifyftp,
1101 'ftps' => \&verifyftp,
1102 'tftp' => \&verifyftp,
1103 'ssh' => \&verifyssh,
1104 'socks' => \&verifysocks,
1105 'gopher' => \&verifyhttp,
1106 'httptls' => \&verifyhttptls);
1109 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1111 my $count = 30; # try for this many seconds
1115 my $fun = $protofunc{$proto};
1117 $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port);
1123 # a real failure, stop trying and bail out
1133 #######################################################################
1134 # start the http server
1137 my ($proto, $verbose, $ipv6, $port) = @_;
1148 # if IPv6, use a different setup
1153 $server = servername_id($proto, $ipvnum, $idnum);
1155 $pidfile = $serverpidfile{$server};
1157 # don't retry if the server doesn't work
1158 if ($doesntrun{$pidfile}) {
1162 my $pid = processexists($pidfile);
1164 stopserver($server, "$pid");
1166 unlink($pidfile) if(-f $pidfile);
1168 $srvrname = servername_str($proto, $ipvnum, $idnum);
1170 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1172 $flags .= "--fork " if($forkserver);
1173 $flags .= "--gopher " if($proto eq "gopher");
1174 $flags .= "--verbose " if($debugprotocol);
1175 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1176 $flags .= "--id $idnum " if($idnum > 1);
1177 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1179 my $cmd = "$perl $srcdir/httpserver.pl $flags";
1180 my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1182 if($httppid <= 0 || !kill(0, $httppid)) {
1184 logmsg "RUN: failed to start the $srvrname server\n";
1185 stopserver($server, "$pid2");
1186 displaylogs($testnumcheck);
1187 $doesntrun{$pidfile} = 1;
1191 # Server is up. Verify that we can speak to it.
1192 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1194 logmsg "RUN: $srvrname server failed verification\n";
1195 # failed to talk to it properly. Kill the server and return failure
1196 stopserver($server, "$httppid $pid2");
1197 displaylogs($testnumcheck);
1198 $doesntrun{$pidfile} = 1;
1204 logmsg "RUN: $srvrname server is now running PID $httppid\n";
1209 return ($httppid, $pid2);
1212 #######################################################################
1213 # start the https stunnel based server
1215 sub runhttpsserver {
1216 my ($verbose, $ipv6, $certfile) = @_;
1217 my $proto = 'https';
1218 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1219 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1231 $server = servername_id($proto, $ipvnum, $idnum);
1233 $pidfile = $serverpidfile{$server};
1235 # don't retry if the server doesn't work
1236 if ($doesntrun{$pidfile}) {
1240 my $pid = processexists($pidfile);
1242 stopserver($server, "$pid");
1244 unlink($pidfile) if(-f $pidfile);
1246 $srvrname = servername_str($proto, $ipvnum, $idnum);
1248 $certfile = 'stunnel.pem' unless($certfile);
1250 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1252 $flags .= "--verbose " if($debugprotocol);
1253 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1254 $flags .= "--id $idnum " if($idnum > 1);
1255 $flags .= "--ipv$ipvnum --proto $proto ";
1256 $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
1257 $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
1258 $flags .= "--connect $HTTPPORT --accept $HTTPSPORT";
1260 my $cmd = "$perl $srcdir/secureserver.pl $flags";
1261 my ($httpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1263 if($httpspid <= 0 || !kill(0, $httpspid)) {
1265 logmsg "RUN: failed to start the $srvrname server\n";
1266 stopserver($server, "$pid2");
1267 displaylogs($testnumcheck);
1268 $doesntrun{$pidfile} = 1;
1272 # Server is up. Verify that we can speak to it.
1273 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $HTTPSPORT);
1275 logmsg "RUN: $srvrname server failed verification\n";
1276 # failed to talk to it properly. Kill the server and return failure
1277 stopserver($server, "$httpspid $pid2");
1278 displaylogs($testnumcheck);
1279 $doesntrun{$pidfile} = 1;
1282 # Here pid3 is actually the pid returned by the unsecure-http server.
1284 $runcert{$server} = $certfile;
1287 logmsg "RUN: $srvrname server is now running PID $httpspid\n";
1292 return ($httpspid, $pid2);
1295 #######################################################################
1296 # start the non-stunnel HTTP TLS extensions capable server
1298 sub runhttptlsserver {
1299 my ($verbose, $ipv6) = @_;
1300 my $proto = "httptls";
1301 my $port = ($ipv6 && ($ipv6 =~ /6$/)) ? $HTTPTLS6PORT : $HTTPTLSPORT;
1302 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1303 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1315 $server = servername_id($proto, $ipvnum, $idnum);
1317 $pidfile = $serverpidfile{$server};
1319 # don't retry if the server doesn't work
1320 if ($doesntrun{$pidfile}) {
1324 my $pid = processexists($pidfile);
1326 stopserver($server, "$pid");
1328 unlink($pidfile) if(-f $pidfile);
1330 $srvrname = servername_str($proto, $ipvnum, $idnum);
1332 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1334 $flags .= "--http ";
1335 $flags .= "--debug 1 " if($debugprotocol);
1336 $flags .= "--port $port ";
1337 $flags .= "--srppasswd certs/srp-verifier-db ";
1338 $flags .= "--srppasswdconf certs/srp-verifier-conf";
1340 my $cmd = "$httptlssrv $flags > $logfile 2>&1";
1341 my ($httptlspid, $pid2) = startnew($cmd, $pidfile, 10, 1); # fake pidfile
1343 if($httptlspid <= 0 || !kill(0, $httptlspid)) {
1345 logmsg "RUN: failed to start the $srvrname server\n";
1346 stopserver($server, "$pid2");
1347 displaylogs($testnumcheck);
1348 $doesntrun{$pidfile} = 1;
1352 # Server is up. Verify that we can speak to it. PID is from fake pidfile
1353 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1355 logmsg "RUN: $srvrname server failed verification\n";
1356 # failed to talk to it properly. Kill the server and return failure
1357 stopserver($server, "$httptlspid $pid2");
1358 displaylogs($testnumcheck);
1359 $doesntrun{$pidfile} = 1;
1365 logmsg "RUN: $srvrname server is now running PID $httptlspid\n";
1370 return ($httptlspid, $pid2);
1373 #######################################################################
1374 # start the pingpong server (FTP, POP3, IMAP, SMTP)
1376 sub runpingpongserver {
1377 my ($proto, $id, $verbose, $ipv6) = @_;
1379 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1380 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1381 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1388 if($proto eq "ftp") {
1389 $port = ($idnum>1)?$FTP2PORT:$FTPPORT;
1392 # if IPv6, use a different setup
1396 elsif($proto eq "pop3") {
1397 $port = ($ipvnum==6) ? $POP36PORT : $POP3PORT;
1399 elsif($proto eq "imap") {
1400 $port = ($ipvnum==6) ? $IMAP6PORT : $IMAPPORT;
1402 elsif($proto eq "smtp") {
1403 $port = ($ipvnum==6) ? $SMTP6PORT : $SMTPPORT;
1406 print STDERR "Unsupported protocol $proto!!\n";
1410 $server = servername_id($proto, $ipvnum, $idnum);
1412 $pidfile = $serverpidfile{$server};
1414 # don't retry if the server doesn't work
1415 if ($doesntrun{$pidfile}) {
1419 my $pid = processexists($pidfile);
1421 stopserver($server, "$pid");
1423 unlink($pidfile) if(-f $pidfile);
1425 $srvrname = servername_str($proto, $ipvnum, $idnum);
1427 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1429 $flags .= "--verbose " if($debugprotocol);
1430 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1431 $flags .= "--srcdir \"$srcdir\" --proto $proto ";
1432 $flags .= "--id $idnum " if($idnum > 1);
1433 $flags .= "--ipv$ipvnum --port $port --addr \"$ip\"";
1435 my $cmd = "$perl $srcdir/ftpserver.pl $flags";
1436 my ($ftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1438 if($ftppid <= 0 || !kill(0, $ftppid)) {
1440 logmsg "RUN: failed to start the $srvrname server\n";
1441 stopserver($server, "$pid2");
1442 displaylogs($testnumcheck);
1443 $doesntrun{$pidfile} = 1;
1447 # Server is up. Verify that we can speak to it.
1448 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1450 logmsg "RUN: $srvrname server failed verification\n";
1451 # failed to talk to it properly. Kill the server and return failure
1452 stopserver($server, "$ftppid $pid2");
1453 displaylogs($testnumcheck);
1454 $doesntrun{$pidfile} = 1;
1461 logmsg "RUN: $srvrname server is now running PID $ftppid\n";
1466 return ($pid2, $ftppid);
1469 #######################################################################
1470 # start the ftps server (or rather, tunnel)
1473 my ($verbose, $ipv6, $certfile) = @_;
1475 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1476 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1488 $server = servername_id($proto, $ipvnum, $idnum);
1490 $pidfile = $serverpidfile{$server};
1492 # don't retry if the server doesn't work
1493 if ($doesntrun{$pidfile}) {
1497 my $pid = processexists($pidfile);
1499 stopserver($server, "$pid");
1501 unlink($pidfile) if(-f $pidfile);
1503 $srvrname = servername_str($proto, $ipvnum, $idnum);
1505 $certfile = 'stunnel.pem' unless($certfile);
1507 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1509 $flags .= "--verbose " if($debugprotocol);
1510 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1511 $flags .= "--id $idnum " if($idnum > 1);
1512 $flags .= "--ipv$ipvnum --proto $proto ";
1513 $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
1514 $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
1515 $flags .= "--connect $FTPPORT --accept $FTPSPORT";
1517 my $cmd = "$perl $srcdir/secureserver.pl $flags";
1518 my ($ftpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1520 if($ftpspid <= 0 || !kill(0, $ftpspid)) {
1522 logmsg "RUN: failed to start the $srvrname server\n";
1523 stopserver($server, "$pid2");
1524 displaylogs($testnumcheck);
1525 $doesntrun{$pidfile} = 1;
1529 # Server is up. Verify that we can speak to it.
1530 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $FTPSPORT);
1532 logmsg "RUN: $srvrname server failed verification\n";
1533 # failed to talk to it properly. Kill the server and return failure
1534 stopserver($server, "$ftpspid $pid2");
1535 displaylogs($testnumcheck);
1536 $doesntrun{$pidfile} = 1;
1539 # Here pid3 is actually the pid returned by the unsecure-ftp server.
1541 $runcert{$server} = $certfile;
1544 logmsg "RUN: $srvrname server is now running PID $ftpspid\n";
1549 return ($ftpspid, $pid2);
1552 #######################################################################
1553 # start the tftp server
1556 my ($id, $verbose, $ipv6) = @_;
1557 my $port = $TFTPPORT;
1561 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1569 # if IPv6, use a different setup
1575 $server = servername_id($proto, $ipvnum, $idnum);
1577 $pidfile = $serverpidfile{$server};
1579 # don't retry if the server doesn't work
1580 if ($doesntrun{$pidfile}) {
1584 my $pid = processexists($pidfile);
1586 stopserver($server, "$pid");
1588 unlink($pidfile) if(-f $pidfile);
1590 $srvrname = servername_str($proto, $ipvnum, $idnum);
1592 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1594 $flags .= "--verbose " if($debugprotocol);
1595 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1596 $flags .= "--id $idnum " if($idnum > 1);
1597 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1599 my $cmd = "$perl $srcdir/tftpserver.pl $flags";
1600 my ($tftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1602 if($tftppid <= 0 || !kill(0, $tftppid)) {
1604 logmsg "RUN: failed to start the $srvrname server\n";
1605 stopserver($server, "$pid2");
1606 displaylogs($testnumcheck);
1607 $doesntrun{$pidfile} = 1;
1611 # Server is up. Verify that we can speak to it.
1612 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1614 logmsg "RUN: $srvrname server failed verification\n";
1615 # failed to talk to it properly. Kill the server and return failure
1616 stopserver($server, "$tftppid $pid2");
1617 displaylogs($testnumcheck);
1618 $doesntrun{$pidfile} = 1;
1624 logmsg "RUN: $srvrname server is now running PID $tftppid\n";
1629 return ($pid2, $tftppid);
1633 #######################################################################
1634 # start the rtsp server
1637 my ($verbose, $ipv6) = @_;
1638 my $port = $RTSPPORT;
1650 # if IPv6, use a different setup
1656 $server = servername_id($proto, $ipvnum, $idnum);
1658 $pidfile = $serverpidfile{$server};
1660 # don't retry if the server doesn't work
1661 if ($doesntrun{$pidfile}) {
1665 my $pid = processexists($pidfile);
1667 stopserver($server, "$pid");
1669 unlink($pidfile) if(-f $pidfile);
1671 $srvrname = servername_str($proto, $ipvnum, $idnum);
1673 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1675 $flags .= "--verbose " if($debugprotocol);
1676 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1677 $flags .= "--id $idnum " if($idnum > 1);
1678 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1680 my $cmd = "$perl $srcdir/rtspserver.pl $flags";
1681 my ($rtsppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1683 if($rtsppid <= 0 || !kill(0, $rtsppid)) {
1685 logmsg "RUN: failed to start the $srvrname server\n";
1686 stopserver($server, "$pid2");
1687 displaylogs($testnumcheck);
1688 $doesntrun{$pidfile} = 1;
1692 # Server is up. Verify that we can speak to it.
1693 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1695 logmsg "RUN: $srvrname server failed verification\n";
1696 # failed to talk to it properly. Kill the server and return failure
1697 stopserver($server, "$rtsppid $pid2");
1698 displaylogs($testnumcheck);
1699 $doesntrun{$pidfile} = 1;
1705 logmsg "RUN: $srvrname server is now running PID $rtsppid\n";
1710 return ($rtsppid, $pid2);
1714 #######################################################################
1715 # Start the ssh (scp/sftp) server
1718 my ($id, $verbose, $ipv6) = @_;
1720 my $port = $SSHPORT;
1721 my $socksport = $SOCKSPORT;
1724 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1731 $server = servername_id($proto, $ipvnum, $idnum);
1733 $pidfile = $serverpidfile{$server};
1735 # don't retry if the server doesn't work
1736 if ($doesntrun{$pidfile}) {
1740 my $pid = processexists($pidfile);
1742 stopserver($server, "$pid");
1744 unlink($pidfile) if(-f $pidfile);
1746 $srvrname = servername_str($proto, $ipvnum, $idnum);
1748 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1750 $flags .= "--verbose " if($verbose);
1751 $flags .= "--debugprotocol " if($debugprotocol);
1752 $flags .= "--pidfile \"$pidfile\" ";
1753 $flags .= "--id $idnum " if($idnum > 1);
1754 $flags .= "--ipv$ipvnum --addr \"$ip\" ";
1755 $flags .= "--sshport $port --socksport $socksport ";
1756 $flags .= "--user \"$USER\"";
1758 my $cmd = "$perl $srcdir/sshserver.pl $flags";
1759 my ($sshpid, $pid2) = startnew($cmd, $pidfile, 60, 0);
1761 # on loaded systems sshserver start up can take longer than the timeout
1762 # passed to startnew, when this happens startnew completes without being
1763 # able to read the pidfile and consequently returns a zero pid2 above.
1765 if($sshpid <= 0 || !kill(0, $sshpid)) {
1767 logmsg "RUN: failed to start the $srvrname server\n";
1768 stopserver($server, "$pid2");
1769 $doesntrun{$pidfile} = 1;
1773 # ssh server verification allows some extra time for the server to start up
1774 # and gives us the opportunity of recovering the pid from the pidfile, when
1775 # this verification succeeds the recovered pid is assigned to pid2.
1777 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1779 logmsg "RUN: $srvrname server failed verification\n";
1780 # failed to fetch server pid. Kill the server and return failure
1781 stopserver($server, "$sshpid $pid2");
1782 $doesntrun{$pidfile} = 1;
1787 # once it is known that the ssh server is alive, sftp server verification
1788 # is performed actually connecting to it, authenticating and performing a
1789 # very simple remote command. This verification is tried only one time.
1791 $sshdlog = server_logfilename($LOGDIR, 'ssh', $ipvnum, $idnum);
1792 $sftplog = server_logfilename($LOGDIR, 'sftp', $ipvnum, $idnum);
1794 if(verifysftp('sftp', $ipvnum, $idnum, $ip, $port) < 1) {
1795 logmsg "RUN: SFTP server failed verification\n";
1796 # failed to talk to it properly. Kill the server and return failure
1798 display_sftpconfig();
1800 display_sshdconfig();
1801 stopserver($server, "$sshpid $pid2");
1802 $doesntrun{$pidfile} = 1;
1807 logmsg "RUN: $srvrname server is now running PID $pid2\n";
1810 return ($pid2, $sshpid);
1813 #######################################################################
1814 # Start the socks server
1816 sub runsocksserver {
1817 my ($id, $verbose, $ipv6) = @_;
1819 my $port = $SOCKSPORT;
1820 my $proto = 'socks';
1822 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1829 $server = servername_id($proto, $ipvnum, $idnum);
1831 $pidfile = $serverpidfile{$server};
1833 # don't retry if the server doesn't work
1834 if ($doesntrun{$pidfile}) {
1838 my $pid = processexists($pidfile);
1840 stopserver($server, "$pid");
1842 unlink($pidfile) if(-f $pidfile);
1844 $srvrname = servername_str($proto, $ipvnum, $idnum);
1846 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1848 # The ssh server must be already running
1850 logmsg "RUN: SOCKS server cannot find running SSH server\n";
1851 $doesntrun{$pidfile} = 1;
1855 # Find out ssh daemon canonical file name
1856 my $sshd = find_sshd();
1858 logmsg "RUN: SOCKS server cannot find $sshdexe\n";
1859 $doesntrun{$pidfile} = 1;
1863 # Find out ssh daemon version info
1864 ($sshdid, $sshdvernum, $sshdverstr, $sshderror) = sshversioninfo($sshd);
1866 # Not an OpenSSH or SunSSH ssh daemon
1867 logmsg "$sshderror\n" if($verbose);
1868 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
1869 $doesntrun{$pidfile} = 1;
1872 logmsg "ssh server found $sshd is $sshdverstr\n" if($verbose);
1874 # Find out ssh client canonical file name
1875 my $ssh = find_ssh();
1877 logmsg "RUN: SOCKS server cannot find $sshexe\n";
1878 $doesntrun{$pidfile} = 1;
1882 # Find out ssh client version info
1883 my ($sshid, $sshvernum, $sshverstr, $ssherror) = sshversioninfo($ssh);
1885 # Not an OpenSSH or SunSSH ssh client
1886 logmsg "$ssherror\n" if($verbose);
1887 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
1888 $doesntrun{$pidfile} = 1;
1892 # Verify minimum ssh client version
1893 if((($sshid =~ /OpenSSH/) && ($sshvernum < 299)) ||
1894 (($sshid =~ /SunSSH/) && ($sshvernum < 100))) {
1895 logmsg "ssh client found $ssh is $sshverstr\n";
1896 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
1897 $doesntrun{$pidfile} = 1;
1900 logmsg "ssh client found $ssh is $sshverstr\n" if($verbose);
1902 # Verify if ssh client and ssh daemon versions match
1903 if(($sshdid ne $sshid) || ($sshdvernum != $sshvernum)) {
1904 # Our test harness might work with slightly mismatched versions
1905 logmsg "Warning: version mismatch: sshd $sshdverstr - ssh $sshverstr\n"
1909 # Config file options for ssh client are previously set from sshserver.pl
1910 if(! -e $sshconfig) {
1911 logmsg "RUN: SOCKS server cannot find $sshconfig\n";
1912 $doesntrun{$pidfile} = 1;
1916 $sshlog = server_logfilename($LOGDIR, 'socks', $ipvnum, $idnum);
1918 # start our socks server
1919 my $cmd="$ssh -N -F $sshconfig $ip > $sshlog 2>&1";
1920 my ($sshpid, $pid2) = startnew($cmd, $pidfile, 30, 1); # fake pidfile
1922 if($sshpid <= 0 || !kill(0, $sshpid)) {
1924 logmsg "RUN: failed to start the $srvrname server\n";
1926 display_sshconfig();
1928 display_sshdconfig();
1929 stopserver($server, "$pid2");
1930 $doesntrun{$pidfile} = 1;
1934 # Ugly hack but ssh doesn't support pid files. PID is from fake pidfile.
1935 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1937 logmsg "RUN: $srvrname server failed verification\n";
1938 # failed to talk to it properly. Kill the server and return failure
1939 stopserver($server, "$sshpid $pid2");
1940 $doesntrun{$pidfile} = 1;
1946 logmsg "RUN: $srvrname server is now running PID $pid2\n";
1949 return ($pid2, $sshpid);
1952 #######################################################################
1953 # Remove all files in the specified directory
1961 opendir(DIR, $dir) ||
1962 return 0; # can't open dir
1963 while($file = readdir(DIR)) {
1964 if($file !~ /^\./) {
1965 unlink("$dir/$file");
1973 #######################################################################
1974 # filter out the specified pattern from the given input file and store the
1975 # results in the given output file
1982 open(IN, "<$infile")
1985 open(OUT, ">$ofile")
1988 # logmsg "FILTER: off $filter from $infile to $ofile\n";
1999 #######################################################################
2000 # compare test results with the expected output, we might filter off
2001 # some pattern that is allowed to differ, output test results
2004 # filter off patterns _before_ this comparison!
2005 my ($subject, $firstref, $secondref)=@_;
2007 my $result = compareparts($firstref, $secondref);
2011 logmsg "\n $subject FAILED:\n";
2012 logmsg showdiff($LOGDIR, $firstref, $secondref);
2021 #######################################################################
2022 # display information about curl and the host the test suite runs on
2026 unlink($memdump); # remove this if there was one left
2035 my $curlverout="$LOGDIR/curlverout.log";
2036 my $curlvererr="$LOGDIR/curlvererr.log";
2037 my $versioncmd="$CURL --version 1>$curlverout 2>$curlvererr";
2039 unlink($curlverout);
2040 unlink($curlvererr);
2042 $versretval = runclient($versioncmd);
2045 open(VERSOUT, "<$curlverout");
2046 @version = <VERSOUT>;
2054 $curl =~ s/^(.*)(libcurl.*)/$1/g;
2057 if($curl =~ /mingw32/) {
2058 # This is a windows minw32 build, we need to translate the
2059 # given path to the "actual" windows path.
2066 # example mount output:
2067 # C:\DOCUME~1\Temp on /tmp type user (binmode,noumount)
2068 # c:\ActiveState\perl on /perl type user (binmode)
2069 # C:\msys\1.0\bin on /usr/bin type user (binmode,cygexec,noumount)
2070 # C:\msys\1.0\bin on /bin type user (binmode,cygexec,noumount)
2072 foreach $mount (@m) {
2073 if( $mount =~ /(.*) on ([^ ]*) type /) {
2074 my ($mingw, $real)=($2, $1);
2075 if($pwd =~ /^$mingw/) {
2076 # the path we got from pwd starts with the path
2077 # we found on this line in the mount output
2079 my $len = length($real);
2080 if($len > $matchlen) {
2081 # we remember the match that is the longest
2089 logmsg "Serious error, can't find our \"real\" path\n";
2092 # now prepend the prefix from the mount command to build
2094 $pwd = "$bestmatch$pwd";
2098 elsif ($curl =~ /win32/) {
2099 # Native Windows builds don't understand the
2100 # output of cygwin's pwd. It will be
2101 # something like /cygdrive/c/<some path>.
2103 # Use the cygpath utility to convert the
2104 # working directory to a Windows friendly
2105 # path. The -m option converts to use drive
2106 # letter:, but it uses / instead \. Forward
2107 # slashes (/) are easier for us. We don't
2108 # have to escape them to get them to curl
2110 chomp($pwd = `cygpath -m $pwd`);
2112 elsif ($libcurl =~ /openssl/i) {
2116 elsif ($libcurl =~ /gnutls/i) {
2120 elsif ($libcurl =~ /nss/i) {
2124 elsif ($libcurl =~ /yassl/i) {
2129 elsif ($libcurl =~ /polarssl/i) {
2134 elsif ($libcurl =~ /axtls/i) {
2139 elsif($_ =~ /^Protocols: (.*)/i) {
2140 # these are the protocols compiled in to this libcurl
2141 @protocols = split(' ', lc($1));
2143 # Generate a "proto-ipv6" version of each protocol to match the
2144 # IPv6 <server> name. This works even if IPv6 support isn't
2145 # compiled in because the <features> test will fail.
2146 push @protocols, map($_ . '-ipv6', @protocols);
2148 # 'none' is used in test cases to mean no server
2149 push @protocols, 'none';
2151 elsif($_ =~ /^Features: (.*)/i) {
2153 if($feat =~ /TrackMemory/i) {
2154 # curl was built with --enable-curldebug (memory tracking)
2157 if($feat =~ /debug/i) {
2158 # curl was built with --enable-debug
2161 if($feat =~ /SSL/i) {
2165 if($feat =~ /Largefile/i) {
2166 # large file support
2169 if($feat =~ /IDN/i) {
2173 if($feat =~ /IPv6/i) {
2176 if($feat =~ /libz/i) {
2179 if($feat =~ /NTLM/i) {
2183 if($feat =~ /NTLM_WB/i) {
2184 # NTLM delegation to winbind daemon ntlm_auth helper enabled
2187 if($feat =~ /CharConv/i) {
2191 if($feat =~ /TLS-SRP/i) {
2197 # Test harness currently uses a non-stunnel server in order to
2198 # run HTTP TLS-SRP tests required when curl is built with https
2199 # protocol support and TLS-SRP feature enabled. For convenience
2200 # 'httptls' may be included in the test harness protocols array
2201 # to differentiate this from classic stunnel based 'https' test
2207 if($_ =~ /^https(-ipv6|)$/) {
2212 if($add_httptls && (! grep /^httptls$/, @protocols)) {
2213 push @protocols, 'httptls';
2214 push @protocols, 'httptls-ipv6';
2219 logmsg "unable to get curl's version, further details are:\n";
2220 logmsg "issued command: \n";
2221 logmsg "$versioncmd \n";
2222 if ($versretval == -1) {
2223 logmsg "command failed with: \n";
2224 logmsg "$versnoexec \n";
2226 elsif ($versretval & 127) {
2227 logmsg sprintf("command died with signal %d, and %s coredump.\n",
2228 ($versretval & 127), ($versretval & 128)?"a":"no");
2231 logmsg sprintf("command exited with value %d \n", $versretval >> 8);
2233 logmsg "contents of $curlverout: \n";
2234 displaylogcontent("$curlverout");
2235 logmsg "contents of $curlvererr: \n";
2236 displaylogcontent("$curlvererr");
2237 die "couldn't get curl's version";
2240 if(-r "../lib/curl_config.h") {
2241 open(CONF, "<../lib/curl_config.h");
2243 if($_ =~ /^\#define HAVE_GETRLIMIT/) {
2251 # client has ipv6 support
2253 # check if the HTTP server has it!
2254 my @sws = `server/sws --version`;
2255 if($sws[0] =~ /IPv6/) {
2256 # HTTP server has ipv6 support!
2261 # check if the FTP server has it!
2262 @sws = `server/sockfilt --version`;
2263 if($sws[0] =~ /IPv6/) {
2264 # FTP server has ipv6 support!
2269 if(!$curl_debug && $torture) {
2270 die "can't run torture tests since curl was not built with curldebug";
2273 $has_shared = `sh $CURLCONFIG --built-shared`;
2276 # curl doesn't list cryptographic support separately, so assume it's
2280 my $hostname=join(' ', runclientoutput("hostname"));
2281 my $hosttype=join(' ', runclientoutput("uname -a"));
2283 logmsg ("********* System characteristics ******** \n",
2286 "* Features: $feat\n",
2287 "* Host: $hostname",
2288 "* System: $hosttype");
2290 logmsg sprintf("* Server SSL: %8s", $stunnel?"ON ":"OFF");
2291 logmsg sprintf(" libcurl SSL: %s\n", $ssl_version?"ON ":"OFF");
2292 logmsg sprintf("* debug build: %8s", $debug_build?"ON ":"OFF");
2293 logmsg sprintf(" track memory: %s\n", $curl_debug?"ON ":"OFF");
2294 logmsg sprintf("* valgrind: %8s", $valgrind?"ON ":"OFF");
2295 logmsg sprintf(" HTTP IPv6 %s\n", $http_ipv6?"ON ":"OFF");
2296 logmsg sprintf("* FTP IPv6 %8s", $ftp_ipv6?"ON ":"OFF");
2297 logmsg sprintf(" Libtool lib: %s\n", $libtool?"ON ":"OFF");
2298 logmsg sprintf("* Shared build: %s\n", $has_shared);
2300 logmsg sprintf("* SSL library: %13s\n", $ssllib);
2303 logmsg "* Ports:\n";
2305 logmsg sprintf("* HTTP/%d ", $HTTPPORT);
2306 logmsg sprintf("FTP/%d ", $FTPPORT);
2307 logmsg sprintf("FTP2/%d ", $FTP2PORT);
2308 logmsg sprintf("RTSP/%d ", $RTSPPORT);
2310 logmsg sprintf("FTPS/%d ", $FTPSPORT);
2311 logmsg sprintf("HTTPS/%d ", $HTTPSPORT);
2313 logmsg sprintf("\n* TFTP/%d ", $TFTPPORT);
2315 logmsg sprintf("HTTP-IPv6/%d ", $HTTP6PORT);
2316 logmsg sprintf("RTSP-IPv6/%d ", $RTSP6PORT);
2319 logmsg sprintf("FTP-IPv6/%d ", $FTP6PORT);
2322 logmsg sprintf("TFTP-IPv6/%d ", $TFTP6PORT);
2324 logmsg sprintf("\n* GOPHER/%d ", $GOPHERPORT);
2326 logmsg sprintf("GOPHER-IPv6/%d", $GOPHERPORT);
2328 logmsg sprintf("\n* SSH/%d ", $SSHPORT);
2329 logmsg sprintf("SOCKS/%d ", $SOCKSPORT);
2330 logmsg sprintf("POP3/%d ", $POP3PORT);
2331 logmsg sprintf("IMAP/%d ", $IMAPPORT);
2332 logmsg sprintf("SMTP/%d\n", $SMTPPORT);
2334 logmsg sprintf("* POP3-IPv6/%d ", $POP36PORT);
2335 logmsg sprintf("IMAP-IPv6/%d ", $IMAP6PORT);
2336 logmsg sprintf("SMTP-IPv6/%d\n", $SMTP6PORT);
2339 logmsg sprintf("* HTTPTLS/%d ", $HTTPTLSPORT);
2341 logmsg sprintf("HTTPTLS-IPv6/%d ", $HTTPTLS6PORT);
2346 $has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys');
2348 logmsg "***************************************** \n";
2351 #######################################################################
2352 # substitute the variable stuff into either a joined up file or
2353 # a command, in either case passed by reference
2360 $$thing =~ s/%FTP6PORT/$FTP6PORT/g;
2361 $$thing =~ s/%FTP2PORT/$FTP2PORT/g;
2362 $$thing =~ s/%FTPSPORT/$FTPSPORT/g;
2363 $$thing =~ s/%FTPPORT/$FTPPORT/g;
2365 $$thing =~ s/%GOPHER6PORT/$GOPHER6PORT/g;
2366 $$thing =~ s/%GOPHERPORT/$GOPHERPORT/g;
2368 $$thing =~ s/%HTTPTLS6PORT/$HTTPTLS6PORT/g;
2369 $$thing =~ s/%HTTPTLSPORT/$HTTPTLSPORT/g;
2370 $$thing =~ s/%HTTP6PORT/$HTTP6PORT/g;
2371 $$thing =~ s/%HTTPSPORT/$HTTPSPORT/g;
2372 $$thing =~ s/%HTTPPORT/$HTTPPORT/g;
2374 $$thing =~ s/%IMAP6PORT/$IMAP6PORT/g;
2375 $$thing =~ s/%IMAPPORT/$IMAPPORT/g;
2377 $$thing =~ s/%POP36PORT/$POP36PORT/g;
2378 $$thing =~ s/%POP3PORT/$POP3PORT/g;
2380 $$thing =~ s/%RTSP6PORT/$RTSP6PORT/g;
2381 $$thing =~ s/%RTSPPORT/$RTSPPORT/g;
2383 $$thing =~ s/%SMTP6PORT/$SMTP6PORT/g;
2384 $$thing =~ s/%SMTPPORT/$SMTPPORT/g;
2386 $$thing =~ s/%SOCKSPORT/$SOCKSPORT/g;
2387 $$thing =~ s/%SSHPORT/$SSHPORT/g;
2389 $$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
2390 $$thing =~ s/%TFTPPORT/$TFTPPORT/g;
2392 # client IP addresses
2394 $$thing =~ s/%CLIENT6IP/$CLIENT6IP/g;
2395 $$thing =~ s/%CLIENTIP/$CLIENTIP/g;
2397 # server IP addresses
2399 $$thing =~ s/%HOST6IP/$HOST6IP/g;
2400 $$thing =~ s/%HOSTIP/$HOSTIP/g;
2404 $$thing =~ s/%CURL/$CURL/g;
2405 $$thing =~ s/%PWD/$pwd/g;
2406 $$thing =~ s/%SRCDIR/$srcdir/g;
2407 $$thing =~ s/%USER/$USER/g;
2409 # The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be
2410 # used for time-out tests and that whould work on most hosts as these
2411 # adjust for the startup/check time for this particular host. We needed
2412 # to do this to make the test suite run better on very slow hosts.
2414 my $ftp2 = $ftpchecktime * 2;
2415 my $ftp3 = $ftpchecktime * 3;
2417 $$thing =~ s/%FTPTIME2/$ftp2/g;
2418 $$thing =~ s/%FTPTIME3/$ftp3/g;
2430 #######################################################################
2431 # Provide time stamps for single test skipped events
2433 sub timestampskippedevents {
2434 my $testnum = $_[0];
2436 return if((not defined($testnum)) || ($testnum < 1));
2440 if($timevrfyend{$testnum}) {
2443 elsif($timesrvrlog{$testnum}) {
2444 $timevrfyend{$testnum} = $timesrvrlog{$testnum};
2447 elsif($timetoolend{$testnum}) {
2448 $timevrfyend{$testnum} = $timetoolend{$testnum};
2449 $timesrvrlog{$testnum} = $timetoolend{$testnum};
2451 elsif($timetoolini{$testnum}) {
2452 $timevrfyend{$testnum} = $timetoolini{$testnum};
2453 $timesrvrlog{$testnum} = $timetoolini{$testnum};
2454 $timetoolend{$testnum} = $timetoolini{$testnum};
2456 elsif($timesrvrend{$testnum}) {
2457 $timevrfyend{$testnum} = $timesrvrend{$testnum};
2458 $timesrvrlog{$testnum} = $timesrvrend{$testnum};
2459 $timetoolend{$testnum} = $timesrvrend{$testnum};
2460 $timetoolini{$testnum} = $timesrvrend{$testnum};
2462 elsif($timesrvrini{$testnum}) {
2463 $timevrfyend{$testnum} = $timesrvrini{$testnum};
2464 $timesrvrlog{$testnum} = $timesrvrini{$testnum};
2465 $timetoolend{$testnum} = $timesrvrini{$testnum};
2466 $timetoolini{$testnum} = $timesrvrini{$testnum};
2467 $timesrvrend{$testnum} = $timesrvrini{$testnum};
2469 elsif($timeprepini{$testnum}) {
2470 $timevrfyend{$testnum} = $timeprepini{$testnum};
2471 $timesrvrlog{$testnum} = $timeprepini{$testnum};
2472 $timetoolend{$testnum} = $timeprepini{$testnum};
2473 $timetoolini{$testnum} = $timeprepini{$testnum};
2474 $timesrvrend{$testnum} = $timeprepini{$testnum};
2475 $timesrvrini{$testnum} = $timeprepini{$testnum};
2480 #######################################################################
2481 # Run a single specified test case
2484 my ($testnum, $count, $total)=@_;
2490 my $disablevalgrind;
2492 # copy test number to a global scope var, this allows
2493 # testnum checking when starting test harness servers.
2494 $testnumcheck = $testnum;
2496 # timestamp test preparation start
2497 $timeprepini{$testnum} = Time::HiRes::time() if($timestats);
2499 if($disttests !~ /test$testnum\W/ ) {
2500 logmsg "Warning: test$testnum not present in tests/data/Makefile.am\n";
2502 if($disabled{$testnum}) {
2503 logmsg "Warning: test$testnum is explicitly disabled\n";
2506 # load the test case file definition
2507 if(loadtest("${TESTDIR}/test${testnum}")) {
2509 # this is not a test
2510 logmsg "RUN: $testnum doesn't look like a test case\n";
2515 @what = getpart("client", "features");
2522 $feature{$f}=$f; # we require this feature
2529 elsif($f eq "OpenSSL") {
2534 elsif($f eq "GnuTLS") {
2539 elsif($f eq "NSS") {
2544 elsif($f eq "axTLS") {
2549 elsif($f eq "unittest") {
2554 elsif($f eq "debug") {
2559 elsif($f eq "large_file") {
2564 elsif($f eq "idn") {
2569 elsif($f eq "ipv6") {
2574 elsif($f eq "libz") {
2579 elsif($f eq "NTLM") {
2584 elsif($f eq "NTLM_WB") {
2589 elsif($f eq "getrlimit") {
2590 if($has_getrlimit) {
2594 elsif($f eq "crypto") {
2599 elsif($f eq "TLS-SRP") {
2604 elsif($f eq "socks") {
2607 # See if this "feature" is in the list of supported protocols
2608 elsif (grep /^\Q$f\E$/i, @protocols) {
2612 $why = "curl lacks $f support";
2617 my @keywords = getpart("info", "keywords");
2620 for $k (@keywords) {
2622 if ($disabled_keywords{$k}) {
2623 $why = "disabled by keyword";
2624 } elsif ($enabled_keywords{$k}) {
2629 if(!$why && !$match && %enabled_keywords) {
2630 $why = "disabled by missing keyword";
2634 # test definition may instruct to (un)set environment vars
2635 # this is done this early, so that the precheck can use environment
2636 # variables and still bail out fine on errors
2638 # restore environment variables that were modified in a previous run
2639 foreach my $var (keys %oldenv) {
2640 if($oldenv{$var} eq 'notset') {
2641 delete $ENV{$var} if($ENV{$var});
2644 $ENV{$var} = $oldenv{$var};
2646 delete $oldenv{$var};
2649 # timestamp required servers verification start
2650 $timesrvrini{$testnum} = Time::HiRes::time() if($timestats);
2653 $why = serverfortest($testnum);
2656 # timestamp required servers verification end
2657 $timesrvrend{$testnum} = Time::HiRes::time() if($timestats);
2659 my @setenv = getpart("client", "setenv");
2661 foreach my $s (@setenv) {
2664 if($s =~ /([^=]*)=(.*)/) {
2665 my ($var, $content) = ($1, $2);
2666 # remember current setting, to restore it once test runs
2667 $oldenv{$var} = ($ENV{$var})?"$ENV{$var}":'notset';
2670 delete $ENV{$var} if($ENV{$var});
2673 if($var =~ /^LD_PRELOAD/) {
2674 if(exe_ext() && (exe_ext() eq '.exe')) {
2675 # print "Skipping LD_PRELOAD due to lack of OS support\n";
2678 if($debug_build || ($has_shared ne "yes")) {
2679 # print "Skipping LD_PRELOAD due to no release shared build\n";
2683 $ENV{$var} = "$content";
2691 # Add a precheck cache. If a precheck command was already invoked
2692 # exactly like this, then use the previous result to speed up
2693 # successive test invokes!
2695 my @precheck = getpart("client", "precheck");
2697 $cmd = $precheck[0];
2701 my @p = split(/ /, $cmd);
2703 # the first word, the command, does not contain a slash so
2704 # we will scan the "improved" PATH to find the command to
2706 my $fullp = checktestcmd($p[0]);
2711 $cmd = join(" ", @p);
2714 my @o = `$cmd 2>/dev/null`;
2719 $why = "precheck command error";
2721 logmsg "prechecked $cmd\n" if($verbose);
2726 if($why && !$listonly) {
2727 # there's a problem, count it as "skipped"
2730 $teststat[$testnum]=$why; # store reason for this test case
2733 printf "test %03d SKIPPED: $why\n", $testnum;
2736 timestampskippedevents($testnum);
2739 logmsg sprintf("test %03d...", $testnum);
2741 # extract the reply data
2742 my @reply = getpart("reply", "data");
2743 my @replycheck = getpart("reply", "datacheck");
2746 # we use this file instead to check the final output against
2748 my %hash = getpartattr("reply", "datacheck");
2749 if($hash{'nonewline'}) {
2750 # Yes, we must cut off the final newline from the final line
2752 chomp($replycheck[$#replycheck]);
2758 # this is the valid protocol blurb curl should generate
2759 my @protocol= fixarray ( getpart("verify", "protocol") );
2761 # redirected stdout/stderr to these files
2762 $STDOUT="$LOGDIR/stdout$testnum";
2763 $STDERR="$LOGDIR/stderr$testnum";
2765 # if this section exists, we verify that the stdout contained this:
2766 my @validstdout = fixarray ( getpart("verify", "stdout") );
2768 # if this section exists, we verify upload
2769 my @upload = getpart("verify", "upload");
2771 # if this section exists, it might be FTP server instructions:
2772 my @ftpservercmd = getpart("reply", "servercmd");
2774 my $CURLOUT="$LOGDIR/curl$testnum.out"; # curl output if not stdout
2777 my @testname= getpart("client", "name");
2780 my $name = $testname[0];
2786 timestampskippedevents($testnum);
2787 return 0; # look successful
2790 my @codepieces = getpart("client", "tool");
2794 $tool = $codepieces[0];
2798 # remove server output logfiles
2803 # write the instructions to file
2804 writearray($FTPDCMD, \@ftpservercmd);
2807 # get the command line options to use
2809 ($cmd, @blaha)= getpart("client", "command");
2812 # make some nice replace operations
2813 $cmd =~ s/\n//g; # no newlines please
2814 # substitute variables in the command line
2818 # there was no command given, use something silly
2825 # create a (possibly-empty) file before starting the test
2826 my @inputfile=getpart("client", "file");
2827 my %fileattr = getpartattr("client", "file");
2828 my $filename=$fileattr{'name'};
2829 if(@inputfile || $filename) {
2831 logmsg "ERROR: section client=>file has no name attribute\n";
2832 timestampskippedevents($testnum);
2835 my $fileContent = join('', @inputfile);
2836 subVariables \$fileContent;
2837 # logmsg "DEBUG: writing file " . $filename . "\n";
2838 open(OUTFILE, ">$filename");
2839 binmode OUTFILE; # for crapage systems, use binary
2840 print OUTFILE $fileContent;
2844 my %cmdhash = getpartattr("client", "command");
2848 if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-output/)) {
2849 #We may slap on --output!
2850 if (!@validstdout) {
2851 $out=" --output $CURLOUT ";
2855 my $serverlogslocktimeout = $defserverlogslocktimeout;
2856 if($cmdhash{'timeout'}) {
2857 # test is allowed to override default server logs lock timeout
2858 if($cmdhash{'timeout'} =~ /(\d+)/) {
2859 $serverlogslocktimeout = $1 if($1 >= 0);
2863 my $postcommanddelay = $defpostcommanddelay;
2864 if($cmdhash{'delay'}) {
2865 # test is allowed to specify a delay after command is executed
2866 if($cmdhash{'delay'} =~ /(\d+)/) {
2867 $postcommanddelay = $1 if($1 > 0);
2873 my $cmdtype = $cmdhash{'type'} || "default";
2874 if($cmdtype eq "perl") {
2875 # run the command line prepended with "perl"
2882 # run curl, add --verbose for debug information output
2883 $cmd = "-1 ".$cmd if(exists $feature{"SSL"} && ($has_axtls));
2886 if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-include/)) {
2887 $inc = "--include ";
2890 $cmdargs ="$out $inc--verbose --trace-time $cmd";
2893 $cmdargs = " $cmd"; # $cmd is the command line for the test file
2894 $CURLOUT = $STDOUT; # sends received data to stdout
2896 if($tool =~ /^lib/) {
2897 $CMDLINE="$LIBDIR/$tool";
2899 elsif($tool =~ /^unit/) {
2900 $CMDLINE="$UNITDIR/$tool";
2904 print "The tool set in the test case for this: '$tool' does not exist\n";
2905 timestampskippedevents($testnum);
2911 my @stdintest = getpart("client", "stdin");
2914 my $stdinfile="$LOGDIR/stdin-for-$testnum";
2915 writearray($stdinfile, \@stdintest);
2917 $cmdargs .= " <$stdinfile";
2925 if($valgrind && !$disablevalgrind) {
2926 my @valgrindoption = getpart("verify", "valgrind");
2927 if((!@valgrindoption) || ($valgrindoption[0] !~ /disable/)) {
2929 my $valgrindcmd = "$valgrind ";
2930 $valgrindcmd .= "$valgrind_tool " if($valgrind_tool);
2931 $valgrindcmd .= "--leak-check=yes ";
2932 $valgrindcmd .= "--num-callers=16 ";
2933 $valgrindcmd .= "${valgrind_logfile}=$LOGDIR/valgrind$testnum";
2934 $CMDLINE = "$valgrindcmd $CMDLINE";
2938 $CMDLINE .= "$cmdargs >$STDOUT 2>$STDERR";
2941 logmsg "$CMDLINE\n";
2944 print CMDLOG "$CMDLINE\n";
2951 # Apr 2007: precommand isn't being used and could be removed
2952 my @precommand= getpart("client", "precommand");
2953 if($precommand[0]) {
2954 # this is pure perl to eval!
2955 my $code = join("", @precommand);
2958 logmsg "perl: $code\n";
2959 logmsg "precommand: $@";
2960 stopservers($verbose);
2961 timestampskippedevents($testnum);
2967 my $gdbinit = "$TESTDIR/gdbinit$testnum";
2968 open(GDBCMD, ">$LOGDIR/gdbcmd");
2969 print GDBCMD "set args $cmdargs\n";
2970 print GDBCMD "show args\n";
2971 print GDBCMD "source $gdbinit\n" if -e $gdbinit;
2975 # timestamp starting of test command
2976 $timetoolini{$testnum} = Time::HiRes::time() if($timestats);
2978 # run the command line we built
2980 $cmdres = torture($CMDLINE,
2981 "$gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
2984 my $GDBW = ($gdbxwin) ? "-w" : "";
2985 runclient("$gdb --directory libtest $DBGCURL $GDBW -x $LOGDIR/gdbcmd");
2986 $cmdres=0; # makes it always continue after a debugged run
2989 $cmdres = runclient("$CMDLINE");
2990 my $signal_num = $cmdres & 127;
2991 $dumped_core = $cmdres & 128;
2993 if(!$anyway && ($signal_num || $dumped_core)) {
2998 $cmdres = (2000 + $signal_num) if($signal_num && !$cmdres);
3002 # timestamp finishing of test command
3003 $timetoolend{$testnum} = Time::HiRes::time() if($timestats);
3007 # there's core file present now!
3013 logmsg "core dumped\n";
3015 logmsg "running gdb for post-mortem analysis:\n";
3016 open(GDBCMD, ">$LOGDIR/gdbcmd2");
3017 print GDBCMD "bt\n";
3019 runclient("$gdb --directory libtest -x $LOGDIR/gdbcmd2 -batch $DBGCURL core ");
3020 # unlink("$LOGDIR/gdbcmd2");
3024 # If a server logs advisor read lock file exists, it is an indication
3025 # that the server has not yet finished writing out all its log files,
3026 # including server request log files used for protocol verification.
3027 # So, if the lock file exists the script waits here a certain amount
3028 # of time until the server removes it, or the given time expires.
3030 if($serverlogslocktimeout) {
3031 my $lockretry = $serverlogslocktimeout * 20;
3032 while((-f $SERVERLOGS_LOCK) && $lockretry--) {
3033 select(undef, undef, undef, 0.05);
3035 if(($lockretry < 0) &&
3036 ($serverlogslocktimeout >= $defserverlogslocktimeout)) {
3037 logmsg "Warning: server logs lock timeout ",
3038 "($serverlogslocktimeout seconds) expired\n";
3042 # Test harness ssh server does not have this synchronization mechanism,
3043 # this implies that some ssh server based tests might need a small delay
3044 # once that the client command has run to avoid false test failures.
3046 # gnutls-serv also lacks this synchronization mechanism, so gnutls-serv
3047 # based tests might need a small delay once that the client command has
3048 # run to avoid false test failures.
3050 sleep($postcommanddelay) if($postcommanddelay);
3052 # timestamp removal of server logs advisor read lock
3053 $timesrvrlog{$testnum} = Time::HiRes::time() if($timestats);
3055 # test definition might instruct to stop some servers
3056 # stop also all servers relative to the given one
3058 my @killtestservers = getpart("client", "killserver");
3059 if(@killtestservers) {
3061 # All servers relative to the given one must be stopped also
3064 foreach my $server (@killtestservers) {
3066 if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
3067 # given a stunnel ssl server, also kill non-ssl underlying one
3068 push @killservers, "${1}${2}";
3070 elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|))$/) {
3071 # given a non-ssl server, also kill stunnel piggybacking one
3072 push @killservers, "${1}s${2}";
3074 elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
3075 # given a socks server, also kill ssh underlying one
3076 push @killservers, "ssh${2}";
3078 elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
3079 # given a ssh server, also kill socks piggybacking one
3080 push @killservers, "socks${2}";
3082 push @killservers, $server;
3085 # kill sockfilter processes for pingpong relative servers
3087 foreach my $server (@killservers) {
3088 if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
3090 my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
3091 my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
3092 killsockfilters($proto, $ipvnum, $idnum, $verbose);
3096 # kill server relative pids clearing them in %run hash
3099 foreach my $server (@killservers) {
3101 $pidlist .= "$run{$server} ";
3104 $runcert{$server} = 0 if($runcert{$server});
3106 killpid($verbose, $pidlist);
3108 # cleanup server pid files
3110 foreach my $server (@killservers) {
3111 my $pidfile = $serverpidfile{$server};
3112 my $pid = processexists($pidfile);
3114 logmsg "Warning: $server server unexpectedly alive\n";
3115 killpid($verbose, $pid);
3117 unlink($pidfile) if(-f $pidfile);
3121 # remove the test server commands file after each test
3124 # run the postcheck command
3125 my @postcheck= getpart("client", "postcheck");
3127 $cmd = $postcheck[0];
3131 logmsg "postcheck $cmd\n" if($verbose);
3132 my $rc = runclient("$cmd");
3133 # Must run the postcheck command in torture mode in order
3134 # to clean up, but the result can't be relied upon.
3135 if($rc != 0 && !$torture) {
3136 logmsg " postcheck FAILED\n";
3137 # timestamp test result verification end
3138 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3144 # restore environment variables that were modified
3146 foreach my $var (keys %oldenv) {
3147 if($oldenv{$var} eq 'notset') {
3148 delete $ENV{$var} if($ENV{$var});
3151 $ENV{$var} = "$oldenv{$var}";
3156 # Skip all the verification on torture tests
3158 if(!$cmdres && !$keepoutfiles) {
3161 # timestamp test result verification end
3162 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3166 my @err = getpart("verify", "errorcode");
3167 my $errorcode = $err[0] || "0";
3171 # verify redirected stdout
3172 my @actual = loadarray($STDOUT);
3174 # variable-replace in the stdout we have from the test case file
3175 @validstdout = fixarray(@validstdout);
3177 # get all attributes
3178 my %hash = getpartattr("verify", "stdout");
3180 # get the mode attribute
3181 my $filemode=$hash{'mode'};
3182 if($filemode && ($filemode eq "text") && $has_textaware) {
3183 # text mode when running on windows: fix line endings
3184 map s/\r\n/\n/g, @actual;
3187 if($hash{'nonewline'}) {
3188 # Yes, we must cut off the final newline from the final line
3189 # of the protocol data
3190 chomp($validstdout[$#validstdout]);
3193 $res = compare("stdout", \@actual, \@validstdout);
3195 # timestamp test result verification end
3196 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3202 $ok .= "-"; # stdout not checked
3205 my %replyattr = getpartattr("reply", "data");
3206 if(!$replyattr{'nocheck'} && (@reply || $replyattr{'sendzero'})) {
3207 # verify the received data
3208 my @out = loadarray($CURLOUT);
3209 my %hash = getpartattr("reply", "data");
3210 # get the mode attribute
3211 my $filemode=$hash{'mode'};
3212 if($filemode && ($filemode eq "text") && $has_textaware) {
3213 # text mode when running on windows: fix line endings
3214 map s/\r\n/\n/g, @out;
3217 $res = compare("data", \@out, \@reply);
3219 # timestamp test result verification end
3220 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3226 $ok .= "-"; # data not checked
3230 # verify uploaded data
3231 my @out = loadarray("$LOGDIR/upload.$testnum");
3232 $res = compare("upload", \@out, \@upload);
3234 # timestamp test result verification end
3235 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3241 $ok .= "-"; # upload not checked
3245 # Verify the sent request
3246 my @out = loadarray($SERVERIN);
3248 # what to cut off from the live protocol sent by curl
3249 my @strip = getpart("verify", "strip");
3251 my @protstrip=@protocol;
3253 # check if there's any attributes on the verify/protocol section
3254 my %hash = getpartattr("verify", "protocol");
3256 if($hash{'nonewline'}) {
3257 # Yes, we must cut off the final newline from the final line
3258 # of the protocol data
3259 chomp($protstrip[$#protstrip]);
3263 # strip off all lines that match the patterns from both arrays
3265 @out = striparray( $_, \@out);
3266 @protstrip= striparray( $_, \@protstrip);
3269 # what parts to cut off from the protocol
3270 my @strippart = getpart("verify", "strippart");
3272 for $strip (@strippart) {
3279 $res = compare("protocol", \@out, \@protstrip);
3281 # timestamp test result verification end
3282 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3290 $ok .= "-"; # protocol not checked
3293 my @outfile=getpart("verify", "file");
3295 # we're supposed to verify a dynamically generated file!
3296 my %hash = getpartattr("verify", "file");
3298 my $filename=$hash{'name'};
3300 logmsg "ERROR: section verify=>file has no name attribute\n";
3301 stopservers($verbose);
3302 # timestamp test result verification end
3303 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3306 my @generated=loadarray($filename);
3308 # what parts to cut off from the file
3309 my @stripfile = getpart("verify", "stripfile");
3311 my $filemode=$hash{'mode'};
3312 if($filemode && ($filemode eq "text") && $has_textaware) {
3313 # text mode when running on windows means adding an extra
3315 push @stripfile, "s/\r\n/\n/";
3319 for $strip (@stripfile) {
3326 @outfile = fixarray(@outfile);
3328 $res = compare("output", \@generated, \@outfile);
3330 # timestamp test result verification end
3331 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3338 $ok .= "-"; # output not checked
3341 # accept multiple comma-separated error codes
3342 my @splerr = split(/ *, */, $errorcode);
3344 foreach my $e (@splerr) {
3357 printf("\n%s returned $cmdres, %d was expected\n",
3358 (!$tool)?"curl":$tool, $errorcode);
3360 logmsg " exit FAILED\n";
3361 # timestamp test result verification end
3362 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3368 logmsg "\n** ALERT! memory debugging with no output file?\n"
3369 if(!$cmdtype eq "perl");
3372 my @memdata=`$memanalyze $memdump`;
3376 # well it could be other memory problems as well, but
3377 # we call it leak for short here
3382 logmsg "\n** MEMORY FAILURE\n";
3384 # timestamp test result verification end
3385 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3394 $ok .= "-"; # memory not checked
3399 unless(opendir(DIR, "$LOGDIR")) {
3400 logmsg "ERROR: unable to read $LOGDIR\n";
3401 # timestamp test result verification end
3402 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3405 my @files = readdir(DIR);
3408 foreach my $file (@files) {
3409 if($file =~ /^valgrind$testnum(\..*|)$/) {
3415 logmsg "ERROR: valgrind log file missing for test $testnum\n";
3416 # timestamp test result verification end
3417 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3420 my @e = valgrindparse($srcdir, $feature{'SSL'}, "$LOGDIR/$vgfile");
3422 logmsg " valgrind ERROR ";
3424 # timestamp test result verification end
3425 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3431 if(!$short && !$disablevalgrind) {
3432 logmsg " valgrind SKIPPED\n";
3434 $ok .= "-"; # skipped
3438 $ok .= "-"; # valgrind not checked
3441 logmsg "$ok " if(!$short);
3443 my $sofar= time()-$start;
3444 my $esttotal = $sofar/$count * $total;
3445 my $estleft = $esttotal - $sofar;
3446 my $left=sprintf("remaining: %02d:%02d",
3449 printf "OK (%-3d out of %-3d, %s)\n", $count, $total, $left;
3451 # the test succeeded, remove all log files
3452 if(!$keepoutfiles) {
3456 # timestamp test result verification end
3457 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3462 #######################################################################
3463 # Stop all running test servers
3466 my $verbose = $_[0];
3468 # kill sockfilter processes for all pingpong servers
3470 killallsockfilters($verbose);
3472 # kill all server pids from %run hash clearing them
3475 foreach my $server (keys %run) {
3479 my $pids = $run{$server};
3480 foreach my $pid (split(' ', $pids)) {
3482 logmsg sprintf("* kill pid for %s => %d\n",
3488 $pidlist .= "$run{$server} ";
3491 $runcert{$server} = 0 if($runcert{$server});
3493 killpid($verbose, $pidlist);
3495 # cleanup all server pid files
3497 foreach my $server (keys %serverpidfile) {
3498 my $pidfile = $serverpidfile{$server};
3499 my $pid = processexists($pidfile);
3501 logmsg "Warning: $server server unexpectedly alive\n";
3502 killpid($verbose, $pid);
3504 unlink($pidfile) if(-f $pidfile);
3508 #######################################################################
3509 # startservers() starts all the named servers
3511 # Returns: string with error reason or blank for success
3517 my (@whatlist) = split(/\s+/,$_);
3518 my $what = lc($whatlist[0]);
3519 $what =~ s/[^a-z0-9-]//g;
3522 if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
3523 $certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem';
3526 if(($what eq "pop3") ||
3528 ($what eq "imap") ||
3529 ($what eq "smtp")) {
3531 ($pid, $pid2) = runpingpongserver($what, "", $verbose);
3533 return "failed starting ". uc($what) ." server";
3535 printf ("* pid $what => %d %d\n", $pid, $pid2) if($verbose);
3536 $run{$what}="$pid $pid2";
3539 elsif($what eq "ftp2") {
3541 ($pid, $pid2) = runpingpongserver("ftp", "2", $verbose);
3543 return "failed starting FTP2 server";
3545 printf ("* pid ftp2 => %d %d\n", $pid, $pid2) if($verbose);
3546 $run{'ftp2'}="$pid $pid2";
3549 elsif($what eq "ftp-ipv6") {
3550 if(!$run{'ftp-ipv6'}) {
3551 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose, "ipv6");
3553 return "failed starting FTP-IPv6 server";
3555 logmsg sprintf("* pid ftp-ipv6 => %d %d\n", $pid,
3556 $pid2) if($verbose);
3557 $run{'ftp-ipv6'}="$pid $pid2";
3560 elsif($what eq "gopher") {
3561 if(!$run{'gopher'}) {
3562 ($pid, $pid2) = runhttpserver("gopher", $verbose, 0,
3565 return "failed starting GOPHER server";
3567 printf ("* pid gopher => %d %d\n", $pid, $pid2) if($verbose);
3568 $run{'gopher'}="$pid $pid2";
3571 elsif($what eq "gopher-ipv6") {
3572 if(!$run{'gopher-ipv6'}) {
3573 ($pid, $pid2) = runhttpserver("gopher", $verbose, "ipv6",
3576 return "failed starting GOPHER-IPv6 server";
3578 logmsg sprintf("* pid gopher-ipv6 => %d %d\n", $pid,
3579 $pid2) if($verbose);
3580 $run{'gopher-ipv6'}="$pid $pid2";
3583 elsif($what eq "http") {
3585 ($pid, $pid2) = runhttpserver("http", $verbose, 0,
3588 return "failed starting HTTP server";
3590 printf ("* pid http => %d %d\n", $pid, $pid2) if($verbose);
3591 $run{'http'}="$pid $pid2";
3594 elsif($what eq "http-ipv6") {
3595 if(!$run{'http-ipv6'}) {
3596 ($pid, $pid2) = runhttpserver("http", $verbose, "IPv6",
3599 return "failed starting HTTP-IPv6 server";
3601 logmsg sprintf("* pid http-ipv6 => %d %d\n", $pid, $pid2)
3603 $run{'http-ipv6'}="$pid $pid2";
3606 elsif($what eq "rtsp") {
3608 ($pid, $pid2) = runrtspserver($verbose);
3610 return "failed starting RTSP server";
3612 printf ("* pid rtsp => %d %d\n", $pid, $pid2) if($verbose);
3613 $run{'rtsp'}="$pid $pid2";
3616 elsif($what eq "rtsp-ipv6") {
3617 if(!$run{'rtsp-ipv6'}) {
3618 ($pid, $pid2) = runrtspserver($verbose, "IPv6");
3620 return "failed starting RTSP-IPv6 server";
3622 logmsg sprintf("* pid rtsp-ipv6 => %d %d\n", $pid, $pid2)
3624 $run{'rtsp-ipv6'}="$pid $pid2";
3627 elsif($what eq "ftps") {
3629 # we can't run ftps tests without stunnel
3630 return "no stunnel";
3633 # we can't run ftps tests if libcurl is SSL-less
3634 return "curl lacks SSL support";
3636 if($runcert{'ftps'} && ($runcert{'ftps'} ne $certfile)) {
3637 # stop server when running and using a different cert
3641 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose);
3643 return "failed starting FTP server";
3645 printf ("* pid ftp => %d %d\n", $pid, $pid2) if($verbose);
3646 $run{'ftp'}="$pid $pid2";
3649 ($pid, $pid2) = runftpsserver($verbose, "", $certfile);
3651 return "failed starting FTPS server (stunnel)";
3653 logmsg sprintf("* pid ftps => %d %d\n", $pid, $pid2)
3655 $run{'ftps'}="$pid $pid2";
3658 elsif($what eq "file") {
3659 # we support it but have no server!
3661 elsif($what eq "https") {
3663 # we can't run https tests without stunnel
3664 return "no stunnel";
3667 # we can't run https tests if libcurl is SSL-less
3668 return "curl lacks SSL support";
3670 if($runcert{'https'} && ($runcert{'https'} ne $certfile)) {
3671 # stop server when running and using a different cert
3672 stopserver('https');
3675 ($pid, $pid2) = runhttpserver("http", $verbose, 0,
3678 return "failed starting HTTP server";
3680 printf ("* pid http => %d %d\n", $pid, $pid2) if($verbose);
3681 $run{'http'}="$pid $pid2";
3683 if(!$run{'https'}) {
3684 ($pid, $pid2) = runhttpsserver($verbose, "", $certfile);
3686 return "failed starting HTTPS server (stunnel)";
3688 logmsg sprintf("* pid https => %d %d\n", $pid, $pid2)
3690 $run{'https'}="$pid $pid2";
3693 elsif($what eq "httptls") {
3695 # for now, we can't run http TLS-EXT tests without gnutls-serv
3696 return "no gnutls-serv";
3698 if(!$run{'httptls'}) {
3699 ($pid, $pid2) = runhttptlsserver($verbose, "IPv4");
3701 return "failed starting HTTPTLS server (gnutls-serv)";
3703 logmsg sprintf("* pid httptls => %d %d\n", $pid, $pid2)
3705 $run{'httptls'}="$pid $pid2";
3708 elsif($what eq "httptls-ipv6") {
3710 # for now, we can't run http TLS-EXT tests without gnutls-serv
3711 return "no gnutls-serv";
3713 if(!$run{'httptls-ipv6'}) {
3714 ($pid, $pid2) = runhttptlsserver($verbose, "IPv6");
3716 return "failed starting HTTPTLS-IPv6 server (gnutls-serv)";
3718 logmsg sprintf("* pid httptls-ipv6 => %d %d\n", $pid, $pid2)
3720 $run{'httptls-ipv6'}="$pid $pid2";
3723 elsif($what eq "tftp") {
3725 ($pid, $pid2) = runtftpserver("", $verbose);
3727 return "failed starting TFTP server";
3729 printf ("* pid tftp => %d %d\n", $pid, $pid2) if($verbose);
3730 $run{'tftp'}="$pid $pid2";
3733 elsif($what eq "tftp-ipv6") {
3734 if(!$run{'tftp-ipv6'}) {
3735 ($pid, $pid2) = runtftpserver("", $verbose, "IPv6");
3737 return "failed starting TFTP-IPv6 server";
3739 printf("* pid tftp-ipv6 => %d %d\n", $pid, $pid2) if($verbose);
3740 $run{'tftp-ipv6'}="$pid $pid2";
3743 elsif($what eq "sftp" || $what eq "scp" || $what eq "socks4" || $what eq "socks5" ) {
3745 ($pid, $pid2) = runsshserver("", $verbose);
3747 return "failed starting SSH server";
3749 printf ("* pid ssh => %d %d\n", $pid, $pid2) if($verbose);
3750 $run{'ssh'}="$pid $pid2";
3752 if($what eq "socks4" || $what eq "socks5") {
3753 if(!$run{'socks'}) {
3754 ($pid, $pid2) = runsocksserver("", $verbose);
3756 return "failed starting socks server";
3758 printf ("* pid socks => %d %d\n", $pid, $pid2) if($verbose);
3759 $run{'socks'}="$pid $pid2";
3762 if($what eq "socks5") {
3764 # Not an OpenSSH or SunSSH ssh daemon
3765 logmsg "Not OpenSSH or SunSSH; socks5 tests need at least OpenSSH 3.7\n";
3766 return "failed starting socks5 server";
3768 elsif(($sshdid =~ /OpenSSH/) && ($sshdvernum < 370)) {
3769 # Need OpenSSH 3.7 for socks5 - http://www.openssh.com/txt/release-3.7
3770 logmsg "$sshdverstr insufficient; socks5 tests need at least OpenSSH 3.7\n";
3771 return "failed starting socks5 server";
3773 elsif(($sshdid =~ /SunSSH/) && ($sshdvernum < 100)) {
3774 # Need SunSSH 1.0 for socks5
3775 logmsg "$sshdverstr insufficient; socks5 tests need at least SunSSH 1.0\n";
3776 return "failed starting socks5 server";
3780 elsif($what eq "none") {
3781 logmsg "* starts no server\n" if ($verbose);
3784 warn "we don't support a server for $what";
3785 return "no server for $what";
3791 ##############################################################################
3792 # This function makes sure the right set of server is running for the
3793 # specified test case. This is a useful design when we run single tests as not
3794 # all servers need to run then!
3796 # Returns: a string, blank if everything is fine or a reason why it failed
3801 my @what = getpart("client", "server");
3804 warn "Test case $testnum has no server(s) specified";
3805 return "no server specified";
3808 for(my $i = scalar(@what) - 1; $i >= 0; $i--) {
3809 my $srvrline = $what[$i];
3810 chomp $srvrline if($srvrline);
3811 if($srvrline =~ /^(\S+)((\s*)(.*))/) {
3812 my $server = "${1}";
3813 my $lnrest = "${2}";
3815 if($server =~ /^(httptls)(\+)(ext|srp)(\d*)(-ipv6|)$/) {
3816 $server = "${1}${4}${5}";
3817 $tlsext = uc("TLS-${3}");
3819 if(! grep /^\Q$server\E$/, @protocols) {
3820 if(substr($server,0,5) ne "socks") {
3822 return "curl lacks $tlsext support";
3825 return "curl lacks $server support";
3829 $what[$i] = "$server$lnrest" if($tlsext);
3833 return &startservers(@what);
3836 #######################################################################
3837 # runtimestats displays test-suite run time statistics
3840 my $lasttest = $_[0];
3842 return if(not $timestats);
3844 logmsg "\nTest suite total running time breakdown per task...\n\n";
3852 my $timesrvrtot = 0.0;
3853 my $timepreptot = 0.0;
3854 my $timetooltot = 0.0;
3855 my $timelocktot = 0.0;
3856 my $timevrfytot = 0.0;
3857 my $timetesttot = 0.0;
3860 for my $testnum (1 .. $lasttest) {
3861 if($timesrvrini{$testnum}) {
3862 $timesrvrtot += $timesrvrend{$testnum} - $timesrvrini{$testnum};
3864 (($timetoolini{$testnum} - $timeprepini{$testnum}) -
3865 ($timesrvrend{$testnum} - $timesrvrini{$testnum}));
3866 $timetooltot += $timetoolend{$testnum} - $timetoolini{$testnum};
3867 $timelocktot += $timesrvrlog{$testnum} - $timetoolend{$testnum};
3868 $timevrfytot += $timevrfyend{$testnum} - $timesrvrlog{$testnum};
3869 $timetesttot += $timevrfyend{$testnum} - $timeprepini{$testnum};
3870 push @timesrvr, sprintf("%06.3f %04d",
3871 $timesrvrend{$testnum} - $timesrvrini{$testnum}, $testnum);
3872 push @timeprep, sprintf("%06.3f %04d",
3873 ($timetoolini{$testnum} - $timeprepini{$testnum}) -
3874 ($timesrvrend{$testnum} - $timesrvrini{$testnum}), $testnum);
3875 push @timetool, sprintf("%06.3f %04d",
3876 $timetoolend{$testnum} - $timetoolini{$testnum}, $testnum);
3877 push @timelock, sprintf("%06.3f %04d",
3878 $timesrvrlog{$testnum} - $timetoolend{$testnum}, $testnum);
3879 push @timevrfy, sprintf("%06.3f %04d",
3880 $timevrfyend{$testnum} - $timesrvrlog{$testnum}, $testnum);
3881 push @timetest, sprintf("%06.3f %04d",
3882 $timevrfyend{$testnum} - $timeprepini{$testnum}, $testnum);
3887 no warnings 'numeric';
3888 @timesrvr = sort { $b <=> $a } @timesrvr;
3889 @timeprep = sort { $b <=> $a } @timeprep;
3890 @timetool = sort { $b <=> $a } @timetool;
3891 @timelock = sort { $b <=> $a } @timelock;
3892 @timevrfy = sort { $b <=> $a } @timevrfy;
3893 @timetest = sort { $b <=> $a } @timetest;
3896 logmsg "Spent ". sprintf("%08.3f ", $timesrvrtot) .
3897 "seconds starting and verifying test harness servers.\n";
3898 logmsg "Spent ". sprintf("%08.3f ", $timepreptot) .
3899 "seconds reading definitions and doing test preparations.\n";
3900 logmsg "Spent ". sprintf("%08.3f ", $timetooltot) .
3901 "seconds actually running test tools.\n";
3902 logmsg "Spent ". sprintf("%08.3f ", $timelocktot) .
3903 "seconds awaiting server logs lock removal.\n";
3904 logmsg "Spent ". sprintf("%08.3f ", $timevrfytot) .
3905 "seconds verifying test results.\n";
3906 logmsg "Spent ". sprintf("%08.3f ", $timetesttot) .
3907 "seconds doing all of the above.\n";
3910 logmsg "\nTest server starting and verification time per test ".
3911 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3912 logmsg "-time- test\n";
3913 logmsg "------ ----\n";
3914 foreach my $txt (@timesrvr) {
3915 last if((not $fullstats) && (not $counter--));
3920 logmsg "\nTest definition reading and preparation time per test ".
3921 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3922 logmsg "-time- test\n";
3923 logmsg "------ ----\n";
3924 foreach my $txt (@timeprep) {
3925 last if((not $fullstats) && (not $counter--));
3930 logmsg "\nTest tool execution time per test ".
3931 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3932 logmsg "-time- test\n";
3933 logmsg "------ ----\n";
3934 foreach my $txt (@timetool) {
3935 last if((not $fullstats) && (not $counter--));
3940 logmsg "\nTest server logs lock removal time per test ".
3941 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3942 logmsg "-time- test\n";
3943 logmsg "------ ----\n";
3944 foreach my $txt (@timelock) {
3945 last if((not $fullstats) && (not $counter--));
3950 logmsg "\nTest results verification time per test ".
3951 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3952 logmsg "-time- test\n";
3953 logmsg "------ ----\n";
3954 foreach my $txt (@timevrfy) {
3955 last if((not $fullstats) && (not $counter--));
3960 logmsg "\nTotal time per test ".
3961 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3962 logmsg "-time- test\n";
3963 logmsg "------ ----\n";
3964 foreach my $txt (@timetest) {
3965 last if((not $fullstats) && (not $counter--));
3972 #######################################################################
3973 # Check options to this test program
3980 if ($ARGV[0] eq "-v") {
3984 elsif($ARGV[0] =~ /^-b(.*)/) {
3986 if($portno =~ s/(\d+)$//) {
3990 elsif ($ARGV[0] eq "-c") {
3991 # use this path to curl instead of default
3992 $DBGCURL=$CURL=$ARGV[1];
3995 elsif ($ARGV[0] eq "-d") {
3996 # have the servers display protocol output
3999 elsif ($ARGV[0] eq "-f") {
4000 # run fork-servers, which makes the server fork for all new
4001 # connections This is NOT what you wanna do without knowing exactly
4005 elsif ($ARGV[0] eq "-g") {
4006 # run this test with gdb
4009 elsif ($ARGV[0] eq "-gw") {
4010 # run this test with windowed gdb
4014 elsif($ARGV[0] eq "-s") {
4018 elsif($ARGV[0] eq "-n") {
4022 elsif($ARGV[0] =~ /^-t(.*)/) {
4027 if($xtra =~ s/(\d+)$//) {
4030 # we undef valgrind to make this fly in comparison
4033 elsif($ARGV[0] eq "-a") {
4034 # continue anyway, even if a test fail
4037 elsif($ARGV[0] eq "-p") {
4040 elsif($ARGV[0] eq "-l") {
4041 # lists the test case names only
4044 elsif($ARGV[0] eq "-k") {
4045 # keep stdout and stderr files after tests
4048 elsif($ARGV[0] eq "-r") {
4049 # run time statistics needs Time::HiRes
4050 if($Time::HiRes::VERSION) {
4051 keys(%timeprepini) = 1000;
4052 keys(%timesrvrini) = 1000;
4053 keys(%timesrvrend) = 1000;
4054 keys(%timetoolini) = 1000;
4055 keys(%timetoolend) = 1000;
4056 keys(%timesrvrlog) = 1000;
4057 keys(%timevrfyend) = 1000;
4062 elsif($ARGV[0] eq "-rf") {
4063 # run time statistics needs Time::HiRes
4064 if($Time::HiRes::VERSION) {
4065 keys(%timeprepini) = 1000;
4066 keys(%timesrvrini) = 1000;
4067 keys(%timesrvrend) = 1000;
4068 keys(%timetoolini) = 1000;
4069 keys(%timetoolend) = 1000;
4070 keys(%timesrvrlog) = 1000;
4071 keys(%timevrfyend) = 1000;
4076 elsif(($ARGV[0] eq "-h") || ($ARGV[0] eq "--help")) {
4079 Usage: runtests.pl [options] [test selection(s)]
4080 -a continue even if a test fails
4081 -bN use base port number N for test servers (default $base)
4082 -c path use this curl executable
4083 -d display server debug info
4084 -g run the test case with gdb
4085 -gw run the test case with gdb as a windowed application
4087 -k keep stdout and stderr files present after tests
4088 -l list all test case names/descriptions
4090 -p print log file contents when a test fails
4091 -r run time statistics
4092 -rf full run time statistics
4094 -t[N] torture (simulate memory alloc failures); N means fail Nth alloc
4096 [num] like "5 6 9" or " 5 to 22 " to run those tests only
4097 [!num] like "!5 !6 !9" to disable those tests
4098 [keyword] like "IPv6" to select only tests containing the key word
4099 [!keyword] like "!cookies" to disable any tests containing the key word
4104 elsif($ARGV[0] =~ /^(\d+)/) {
4107 for($fromnum .. $number) {
4116 elsif($ARGV[0] =~ /^to$/i) {
4117 $fromnum = $number+1;
4119 elsif($ARGV[0] =~ /^!(\d+)/) {
4123 elsif($ARGV[0] =~ /^!(.+)/) {
4124 $disabled_keywords{$1}=$1;
4126 elsif($ARGV[0] =~ /^([-[{a-zA-Z].*)/) {
4127 $enabled_keywords{$1}=$1;
4130 print "Unknown option: $ARGV[0]\n";
4136 if(@testthis && ($testthis[0] ne "")) {
4137 $TESTCASES=join(" ", @testthis);
4141 # we have found valgrind on the host, use it
4143 # verify that we can invoke it fine
4144 my $code = runclient("valgrind >/dev/null 2>&1");
4146 if(($code>>8) != 1) {
4147 #logmsg "Valgrind failure, disable it\n";
4151 # since valgrind 2.1.x, '--tool' option is mandatory
4152 # use it, if it is supported by the version installed on the system
4153 runclient("valgrind --help 2>&1 | grep -- --tool > /dev/null 2>&1");
4155 $valgrind_tool="--tool=memcheck";
4160 # A shell script. This is typically when built with libtool,
4161 $valgrind="../libtool --mode=execute $valgrind";
4165 # valgrind 3 renamed the --logfile option to --log-file!!!
4166 my $ver=join(' ', runclientoutput("valgrind --version"));
4167 # cut off all but digits and dots
4168 $ver =~ s/[^0-9.]//g;
4170 if($ver =~ /^(\d+)/) {
4173 $valgrind_logfile="--log-file";
4180 # open the executable curl and read the first 4 bytes of it
4181 open(CHECK, "<$CURL");
4183 sysread CHECK, $c, 4;
4186 # A shell script. This is typically when built with libtool,
4188 $gdb = "libtool --mode=execute gdb";
4192 $HTTPPORT = $base++; # HTTP server port
4193 $HTTPSPORT = $base++; # HTTPS (stunnel) server port
4194 $FTPPORT = $base++; # FTP server port
4195 $FTPSPORT = $base++; # FTPS (stunnel) server port
4196 $HTTP6PORT = $base++; # HTTP IPv6 server port
4197 $FTP2PORT = $base++; # FTP server 2 port
4198 $FTP6PORT = $base++; # FTP IPv6 port
4199 $TFTPPORT = $base++; # TFTP (UDP) port
4200 $TFTP6PORT = $base++; # TFTP IPv6 (UDP) port
4201 $SSHPORT = $base++; # SSH (SCP/SFTP) port
4202 $SOCKSPORT = $base++; # SOCKS port
4203 $POP3PORT = $base++; # POP3 server port
4204 $POP36PORT = $base++; # POP3 IPv6 server port
4205 $IMAPPORT = $base++; # IMAP server port
4206 $IMAP6PORT = $base++; # IMAP IPv6 server port
4207 $SMTPPORT = $base++; # SMTP server port
4208 $SMTP6PORT = $base++; # SMTP IPv6 server port
4209 $RTSPPORT = $base++; # RTSP server port
4210 $RTSP6PORT = $base++; # RTSP IPv6 server port
4211 $GOPHERPORT = $base++; # Gopher IPv4 server port
4212 $GOPHER6PORT = $base++; # Gopher IPv6 server port
4213 $HTTPTLSPORT = $base++; # HTTP TLS (non-stunnel) server port
4214 $HTTPTLS6PORT = $base++; # HTTP TLS (non-stunnel) IPv6 server port
4216 #######################################################################
4217 # clear and create logging directory:
4221 mkdir($LOGDIR, 0777);
4223 #######################################################################
4224 # initialize some variables
4228 init_serverpidfile_hash();
4230 #######################################################################
4231 # Output curl version and host info being tested
4238 #######################################################################
4239 # Fetch all disabled tests
4242 open(D, "<$TESTDIR/DISABLED");
4249 $disabled{$1}=$1; # disable this test number
4254 #######################################################################
4255 # If 'all' tests are requested, find out all test numbers
4258 if ( $TESTCASES eq "all") {
4259 # Get all commands and find out their test numbers
4260 opendir(DIR, $TESTDIR) || die "can't opendir $TESTDIR: $!";
4261 my @cmds = grep { /^test([0-9]+)$/ && -f "$TESTDIR/$_" } readdir(DIR);
4264 $TESTCASES=""; # start with no test cases
4266 # cut off everything but the digits
4268 $_ =~ s/[a-z\/\.]*//g;
4270 # sort the numbers from low to high
4271 foreach my $n (sort { $a <=> $b } @cmds) {
4273 # skip disabled test cases
4274 my $why = "configured as DISABLED";
4277 $teststat[$n]=$why; # store reason for this test case
4280 $TESTCASES .= " $n";
4284 #######################################################################
4285 # Start the command line log
4287 open(CMDLOG, ">$CURLLOG") ||
4288 logmsg "can't log command lines to $CURLLOG\n";
4290 #######################################################################
4292 # Display the contents of the given file. Line endings are canonicalized
4293 # and excessively long files are elided
4294 sub displaylogcontent {
4296 if(open(SINGLE, "<$file")) {
4300 while(my $string = <SINGLE>) {
4301 $string =~ s/\r\n/\n/g;
4302 $string =~ s/[\r\f\032]/\n/g;
4303 $string .= "\n" unless ($string =~ /\n$/);
4305 for my $line (split("\n", $string)) {
4306 $line =~ s/\s*\!$//;
4308 push @tail, " $line\n";
4313 $truncate = $linecount > 1000;
4319 my $tailtotal = scalar @tail;
4320 if($tailtotal > $tailshow) {
4321 $tailskip = $tailtotal - $tailshow;
4322 logmsg "=== File too long: $tailskip lines omitted here\n";
4324 for($tailskip .. $tailtotal-1) {
4334 opendir(DIR, "$LOGDIR") ||
4335 die "can't open dir: $!";
4336 my @logs = readdir(DIR);
4339 logmsg "== Contents of files in the $LOGDIR/ dir after test $testnum\n";
4340 foreach my $log (sort @logs) {
4341 if($log =~ /\.(\.|)$/) {
4342 next; # skip "." and ".."
4344 if($log =~ /^\.nfs/) {
4347 if(($log eq "memdump") || ($log eq "core")) {
4348 next; # skip "memdump" and "core"
4350 if((-d "$LOGDIR/$log") || (! -s "$LOGDIR/$log")) {
4351 next; # skip directory and empty files
4353 if(($log =~ /^stdout\d+/) && ($log !~ /^stdout$testnum/)) {
4354 next; # skip stdoutNnn of other tests
4356 if(($log =~ /^stderr\d+/) && ($log !~ /^stderr$testnum/)) {
4357 next; # skip stderrNnn of other tests
4359 if(($log =~ /^upload\d+/) && ($log !~ /^upload$testnum/)) {
4360 next; # skip uploadNnn of other tests
4362 if(($log =~ /^curl\d+\.out/) && ($log !~ /^curl$testnum\.out/)) {
4363 next; # skip curlNnn.out of other tests
4365 if(($log =~ /^test\d+\.txt/) && ($log !~ /^test$testnum\.txt/)) {
4366 next; # skip testNnn.txt of other tests
4368 if(($log =~ /^file\d+\.txt/) && ($log !~ /^file$testnum\.txt/)) {
4369 next; # skip fileNnn.txt of other tests
4371 if(($log =~ /^netrc\d+/) && ($log !~ /^netrc$testnum/)) {
4372 next; # skip netrcNnn of other tests
4374 if(($log =~ /^valgrind\d+/) && ($log !~ /^valgrind$testnum(\..*|)$/)) {
4375 next; # skip valgrindNnn of other tests
4377 logmsg "=== Start of file $log\n";
4378 displaylogcontent("$LOGDIR/$log");
4379 logmsg "=== End of file $log\n";
4383 #######################################################################
4384 # The main test-loop
4392 my @at = split(" ", $TESTCASES);
4397 foreach $testnum (@at) {
4399 $lasttest = $testnum if($testnum > $lasttest);
4402 my $error = singletest($testnum, $count, scalar(@at));
4404 # not a test we can run
4408 $total++; # number of tests we've run
4411 $failed.= "$testnum ";
4413 # display all files in log/ in a nice way
4414 displaylogs($testnum);
4417 # a test failed, abort
4418 logmsg "\n - abort tests\n";
4423 $ok++; # successful test counter
4426 # loop for next test
4429 my $sofar = time() - $start;
4431 #######################################################################
4436 # Tests done, stop the servers
4437 stopservers($verbose);
4439 my $all = $total + $skipped;
4441 runtimestats($lasttest);
4444 logmsg sprintf("TESTDONE: $ok tests out of $total reported OK: %d%%\n",
4448 logmsg "TESTFAIL: These test cases failed: $failed\n";
4452 logmsg "TESTFAIL: No tests were performed\n";
4456 logmsg "TESTDONE: $all tests were considered during ".
4457 sprintf("%.0f", $sofar) ." seconds.\n";
4460 if($skipped && !$short) {
4462 logmsg "TESTINFO: $skipped tests were skipped due to these restraints:\n";
4464 for(keys %skipped) {
4466 printf "TESTINFO: \"%s\" %d times (", $r, $skipped{$_};
4468 # now show all test case numbers that had this reason for being
4471 for(0 .. scalar @teststat) {
4473 if($teststat[$_] && ($teststat[$_] eq $r)) {
4483 if($total && ($ok != $total)) {