2 #***************************************************************************
4 # Project ___| | | | _ \| |
6 # | (__| |_| | _ <| |___
7 # \___|\___/|_| \_\_____|
9 # Copyright (C) 1998 - 2012, 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
141 my $HTTPPROXYPORT; # HTTP proxy port, when using CONNECT
143 my $srcdir = $ENV{'srcdir'} || '.';
144 my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
145 my $VCURL=$CURL; # what curl binary to use to verify the servers with
146 # VCURL is handy to set to the system one when the one you
147 # just built hangs or crashes and thus prevent verification
148 my $DBGCURL=$CURL; #"../src/.libs/curl"; # alternative for debugging
150 my $TESTDIR="$srcdir/data";
151 my $LIBDIR="./libtest";
152 my $UNITDIR="./unit";
153 # TODO: change this to use server_inputfilename()
154 my $SERVERIN="$LOGDIR/server.input"; # what curl sent the server
155 my $SERVER2IN="$LOGDIR/server2.input"; # what curl sent the second server
156 my $PROXYIN="$LOGDIR/proxy.input"; # what curl sent the proxy
157 my $CURLLOG="$LOGDIR/curl.log"; # all command lines run
158 my $FTPDCMD="$LOGDIR/ftpserver.cmd"; # copy ftp server instructions here
159 my $SERVERLOGS_LOCK="$LOGDIR/serverlogs.lock"; # server logs advisor read lock
160 my $CURLCONFIG="../curl-config"; # curl-config from current build
162 # Normally, all test cases should be run, but at times it is handy to
163 # simply run a particular one:
166 # To run specific test cases, set them like:
167 # $TESTCASES="1 2 3 7 8";
169 #######################################################################
170 # No variables below this point should need to be modified
173 # invoke perl like this:
174 my $perl="perl -I$srcdir";
175 my $server_response_maxtime=13;
177 my $debug_build=0; # curl built with --enable-debug
178 my $curl_debug=0; # curl built with --enable-curldebug (memory tracking)
181 # name of the file that the memory debugging creates:
182 my $memdump="$LOGDIR/memdump";
184 # the path to the script that analyzes the memory debug output file:
185 my $memanalyze="$perl $srcdir/memanalyze.pl";
187 my $pwd = getcwd(); # current working directory
191 my $ftpchecktime=1; # time it took to verify our test FTP server
193 my $stunnel = checkcmd("stunnel4") || checkcmd("stunnel");
194 my $valgrind = checktestcmd("valgrind");
195 my $valgrind_logfile="--logfile";
197 my $gdb = checktestcmd("gdb");
198 my $httptlssrv = find_httptlssrv();
200 my $ssl_version; # set if libcurl is built with SSL support
201 my $large_file; # set if libcurl is built with large file support
202 my $has_idn; # set if libcurl is built with IDN support
203 my $http_ipv6; # set if HTTP server has IPv6 support
204 my $ftp_ipv6; # set if FTP server has IPv6 support
205 my $tftp_ipv6; # set if TFTP server has IPv6 support
206 my $gopher_ipv6; # set if Gopher server has IPv6 support
207 my $has_ipv6; # set if libcurl is built with IPv6 support
208 my $has_libz; # set if libcurl is built with libz support
209 my $has_getrlimit; # set if system has getrlimit()
210 my $has_ntlm; # set if libcurl is built with NTLM support
211 my $has_ntlm_wb; # set if libcurl is built with NTLM delegation to winbind
212 my $has_charconv;# set if libcurl is built with CharConv support
213 my $has_tls_srp; # set if libcurl is built with TLS-SRP support
214 my $has_metalink;# set if curl is built with Metalink support
216 my $has_openssl; # built with a lib using an OpenSSL-like API
217 my $has_gnutls; # built with GnuTLS
218 my $has_nss; # built with NSS
219 my $has_yassl; # built with yassl
220 my $has_polarssl;# built with polarssl
221 my $has_axtls; # built with axTLS
222 my $has_winssl; # built with WinSSL (Schannel/SSPI)
224 my $has_shared = "unknown"; # built shared
226 my $ssllib; # name of the lib we use (for human presentation)
227 my $has_crypto; # set if libcurl is built with cryptographic support
228 my $has_textaware; # set if running on a system that has a text mode concept
229 # on files. Windows for example
231 my @protocols; # array of lowercase supported protocol servers
233 my $skipped=0; # number of tests skipped; reported in main loop
234 my %skipped; # skipped{reason}=counter, reasons for skip
235 my @teststat; # teststat[testnum]=reason, reasons for skip
236 my %disabled_keywords; # key words of tests to skip
237 my %enabled_keywords; # key words of tests to run
238 my %disabled; # disabled test cases
240 my $sshdid; # for socks server, ssh daemon version id
241 my $sshdvernum; # for socks server, ssh daemon version number
242 my $sshdverstr; # for socks server, ssh daemon version string
243 my $sshderror; # for socks server, ssh daemon version error
245 my $defserverlogslocktimeout = 20; # timeout to await server logs lock removal
246 my $defpostcommanddelay = 0; # delay between command and postcheck sections
248 my $timestats; # time stamping and stats generation
249 my $fullstats; # show time stats for every single test
250 my %timeprepini; # timestamp for each test preparation start
251 my %timesrvrini; # timestamp for each test required servers verification start
252 my %timesrvrend; # timestamp for each test required servers verification end
253 my %timetoolini; # timestamp for each test command run starting
254 my %timetoolend; # timestamp for each test command run stopping
255 my %timesrvrlog; # timestamp for each test server logs lock removal
256 my %timevrfyend; # timestamp for each test result verification end
258 my $testnumcheck; # test number, set in singletest sub.
261 #######################################################################
262 # variables that command line options may set
269 my $gdbthis; # run test case with gdb debugger
270 my $gdbxwin; # use windowed gdb when using gdb
271 my $keepoutfiles; # keep stdout and stderr files after tests
272 my $listonly; # only list the tests
273 my $postmortem; # display detailed info about failed tests
275 my %run; # running server
276 my %doesntrun; # servers that don't work, identified by pidfile
277 my %serverpidfile;# all server pid file names, identified by server id
278 my %runcert; # cert file currently in use by an ssl running server
280 # torture test variables
285 #######################################################################
286 # logmsg is our general message logging subroutine.
294 # get the name of the current user
295 my $USER = $ENV{USER}; # Linux
297 $USER = $ENV{USERNAME}; # Windows
299 $USER = $ENV{LOGNAME}; # Some UNIX (I think)
303 # enable memory debugging if curl is compiled with it
304 $ENV{'CURL_MEMDEBUG'} = $memdump;
309 logmsg "runtests.pl received SIG$signame, exiting\n";
310 stopservers($verbose);
311 die "Somebody sent me a SIG$signame";
313 $SIG{INT} = \&catch_zap;
314 $SIG{TERM} = \&catch_zap;
316 ##########################################################################
317 # Clear all possible '*_proxy' environment variables for various protocols
318 # to prevent them to interfere with our testing!
321 foreach $protocol (('ftp', 'http', 'ftps', 'https', 'no', 'all')) {
322 my $proxy = "${protocol}_proxy";
323 # clear lowercase version
324 delete $ENV{$proxy} if($ENV{$proxy});
325 # clear uppercase version
326 delete $ENV{uc($proxy)} if($ENV{uc($proxy)});
329 # make sure we don't get affected by other variables that control our
332 delete $ENV{'SSL_CERT_DIR'} if($ENV{'SSL_CERT_DIR'});
333 delete $ENV{'SSL_CERT_PATH'} if($ENV{'SSL_CERT_PATH'});
334 delete $ENV{'CURL_CA_BUNDLE'} if($ENV{'CURL_CA_BUNDLE'});
336 #######################################################################
337 # Load serverpidfile hash with pidfile names for all possible servers.
339 sub init_serverpidfile_hash {
340 for my $proto (('ftp', 'http', 'imap', 'pop3', 'smtp')) {
341 for my $ssl (('', 's')) {
342 for my $ipvnum ((4, 6)) {
343 for my $idnum ((1, 2)) {
344 my $serv = servername_id("$proto$ssl", $ipvnum, $idnum);
345 my $pidf = server_pidfilename("$proto$ssl", $ipvnum, $idnum);
346 $serverpidfile{$serv} = $pidf;
351 for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp', 'gopher', 'httptls')) {
352 for my $ipvnum ((4, 6)) {
353 for my $idnum ((1, 2)) {
354 my $serv = servername_id($proto, $ipvnum, $idnum);
355 my $pidf = server_pidfilename($proto, $ipvnum, $idnum);
356 $serverpidfile{$serv} = $pidf;
362 #######################################################################
363 # Check if a given child process has just died. Reaps it if so.
366 use POSIX ":sys_wait_h";
368 if(not defined $pid || $pid <= 0) {
371 my $rc = waitpid($pid, &WNOHANG);
372 return ($rc == $pid)?1:0;
375 #######################################################################
376 # Start a new thread/process and run the given command line in there.
377 # Return the pids (yes plural) of the new child process to the parent.
380 my ($cmd, $pidfile, $timeout, $fake)=@_;
382 logmsg "startnew: $cmd\n" if ($verbose);
387 if(not defined $child) {
388 logmsg "startnew: fork() failure detected\n";
393 # Here we are the child. Run the given command.
395 # Put an "exec" in front of the command so that the child process
396 # keeps this child's process ID.
397 exec("exec $cmd") || die "Can't exec() $cmd: $!";
399 # exec() should never return back here to this process. We protect
400 # ourselves by calling die() just in case something goes really bad.
401 die "error: exec() has returned";
404 # Ugly hack but ssh client and gnutls-serv don't support pid files
406 if(open(OUT, ">$pidfile")) {
407 print OUT $child . "\n";
409 logmsg "startnew: $pidfile faked with pid=$child\n" if($verbose);
412 logmsg "startnew: failed to write fake $pidfile with pid=$child\n";
414 # could/should do a while connect fails sleep a bit and loop
416 if (checkdied($child)) {
417 logmsg "startnew: child process has failed to start\n" if($verbose);
422 my $count = $timeout;
424 if(-f $pidfile && -s $pidfile && open(PID, "<$pidfile")) {
427 if(($pid2 > 0) && kill(0, $pid2)) {
428 # if $pid2 is valid, then make sure this pid is alive, as
429 # otherwise it is just likely to be the _previous_ pidfile or
433 # invalidate $pid2 if not actually alive
436 if (checkdied($child)) {
437 logmsg "startnew: child process has died, server might start up\n"
439 # We can't just abort waiting for the server with a
441 # because the server might have forked and could still start
442 # up normally. Instead, just reduce the amount of time we remain
449 # Return two PIDs, the one for the child process we spawned and the one
450 # reported by the server itself (in case it forked again on its own).
451 # Both (potentially) need to be killed at the end of the test.
452 return ($child, $pid2);
456 #######################################################################
457 # Check for a command in the PATH of the test server.
461 my @paths=(split(":", $ENV{'PATH'}), "/usr/sbin", "/usr/local/sbin",
462 "/sbin", "/usr/bin", "/usr/local/bin",
463 "./libtest/.libs", "./libtest");
465 if( -x "$_/$cmd" && ! -d "$_/$cmd") {
466 # executable bit but not a directory!
472 #######################################################################
473 # Get the list of tests that the tests/data/Makefile.am knows about!
477 my @dist = `cd data && make show`;
478 $disttests = join("", @dist);
481 #######################################################################
482 # Check for a command in the PATH of the machine running curl.
486 return checkcmd($cmd);
489 #######################################################################
490 # Run the application under test and return its return code
496 # This is one way to test curl on a remote machine
497 # my $out = system("ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'");
498 # sleep 2; # time to allow the NFS server to be updated
502 #######################################################################
503 # Run the application under test and return its stdout
505 sub runclientoutput {
509 # This is one way to test curl on a remote machine
510 # my @out = `ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'`;
511 # sleep 2; # time to allow the NFS server to be updated
515 #######################################################################
516 # Memory allocation test and failure torture testing.
522 # remove memdump first to be sure we get a new nice and clean one
525 # First get URL from test server, ignore the output/result
528 logmsg " CMD: $testcmd\n" if($verbose);
530 # memanalyze -v is our friend, get the number of allocations made
532 my @out = `$memanalyze -v $memdump`;
534 if(/^Allocations: (\d+)/) {
540 logmsg " found no allocs to make fail\n";
544 logmsg " $count allocations to make fail\n";
546 for ( 1 .. $count ) {
551 if($tortalloc && ($tortalloc != $limit)) {
556 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
558 my $now = sprintf("%02d:%02d:%02d ", $hour, $min, $sec);
559 logmsg "Fail alloc no: $limit at $now\r";
562 # make the memory allocation function number $limit return failure
563 $ENV{'CURL_MEMLIMIT'} = $limit;
565 # remove memdump first to be sure we get a new nice and clean one
568 logmsg "*** Alloc number $limit is now set to fail ***\n" if($gdbthis);
575 $ret = runclient($testcmd);
577 #logmsg "$_ Returned " . $ret >> 8 . "\n";
579 # Now clear the variable again
580 delete $ENV{'CURL_MEMLIMIT'} if($ENV{'CURL_MEMLIMIT'});
583 # there's core file present now!
584 logmsg " core dumped\n";
589 # verify that it returns a proper error code, doesn't leak memory
590 # and doesn't core dump
592 logmsg " system() returned $ret\n";
596 my @memdata=`$memanalyze $memdump`;
600 # well it could be other memory problems as well, but
601 # we call it leak for short here
606 logmsg "** MEMORY FAILURE\n";
608 logmsg `$memanalyze -l $memdump`;
613 logmsg " Failed on alloc number $limit in test.\n",
614 " invoke with \"-t$limit\" to repeat this single case.\n";
615 stopservers($verbose);
620 logmsg "torture OK\n";
624 #######################################################################
625 # Stop a test server along with pids which aren't in the %run hash yet.
626 # This also stops all servers which are relative to the given one.
629 my ($server, $pidlist) = @_;
631 # kill sockfilter processes for pingpong relative server
633 if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
635 my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
636 my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
637 killsockfilters($proto, $ipvnum, $idnum, $verbose);
640 # All servers relative to the given one must be stopped also
643 if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
644 # given a stunnel based ssl server, also kill non-ssl underlying one
645 push @killservers, "${1}${2}";
647 elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|))$/) {
648 # given a non-ssl server, also kill stunnel based ssl piggybacking one
649 push @killservers, "${1}s${2}";
651 elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
652 # given a socks server, also kill ssh underlying one
653 push @killservers, "ssh${2}";
655 elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
656 # given a ssh server, also kill socks piggybacking one
657 push @killservers, "socks${2}";
659 push @killservers, $server;
661 # kill given pids and server relative ones clearing them in %run hash
663 foreach my $server (@killservers) {
665 # we must prepend a space since $pidlist may already contain a pid
666 $pidlist .= " $run{$server}";
669 $runcert{$server} = 0 if($runcert{$server});
671 killpid($verbose, $pidlist);
673 # cleanup server pid files
675 foreach my $server (@killservers) {
676 my $pidfile = $serverpidfile{$server};
677 my $pid = processexists($pidfile);
679 logmsg "Warning: $server server unexpectedly alive\n";
680 killpid($verbose, $pid);
682 unlink($pidfile) if(-f $pidfile);
686 #######################################################################
687 # Verify that the server that runs on $ip, $port is our server. This also
688 # implies that we can speak with it, as there might be occasions when the
689 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
690 # assign requested address")
693 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
694 my $server = servername_id($proto, $ipvnum, $idnum);
698 my $verifyout = "$LOGDIR/".
699 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
700 unlink($verifyout) if(-f $verifyout);
702 my $verifylog = "$LOGDIR/".
703 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
704 unlink($verifylog) if(-f $verifylog);
706 if($proto eq "gopher") {
711 my $flags = "--max-time $server_response_maxtime ";
712 $flags .= "--output $verifyout ";
713 $flags .= "--silent ";
714 $flags .= "--verbose ";
715 $flags .= "--globoff ";
716 $flags .= "-1 " if($has_axtls);
717 $flags .= "--insecure " if($proto eq 'https');
718 $flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\"";
720 my $cmd = "$VCURL $flags 2>$verifylog";
722 # verify if our/any server is running on this port
723 logmsg "RUN: $cmd\n" if($verbose);
724 my $res = runclient($cmd);
726 $res >>= 8; # rotate the result
728 logmsg "RUN: curl command died with a coredump\n";
732 if($res && $verbose) {
733 logmsg "RUN: curl command returned $res\n";
734 if(open(FILE, "<$verifylog")) {
735 while(my $string = <FILE>) {
736 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
743 if(open(FILE, "<$verifyout")) {
744 while(my $string = <FILE>) {
746 last; # only want first line
751 if($data && ($data =~ /WE ROOLZ: (\d+)/)) {
755 # curl: (6) Couldn't resolve host '::1'
756 logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
759 elsif($data || ($res && ($res != 7))) {
760 logmsg "RUN: Unknown server on our $server port: $port ($res)\n";
766 #######################################################################
767 # Verify that the server that runs on $ip, $port is our server. This also
768 # implies that we can speak with it, as there might be occasions when the
769 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
770 # assign requested address")
773 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
774 my $server = servername_id($proto, $ipvnum, $idnum);
779 my $verifylog = "$LOGDIR/".
780 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
781 unlink($verifylog) if(-f $verifylog);
783 if($proto eq "ftps") {
784 $extra .= "--insecure --ftp-ssl-control ";
786 elsif($proto eq "smtp") {
787 # SMTP is a bit different since it requires more options and it
789 $extra .= "--mail-rcpt verifiedserver ";
790 $extra .= "--mail-from fake ";
791 $extra .= "--upload /dev/null ";
792 $extra .= "--stderr - "; # move stderr to parse the verbose stuff
795 my $flags = "--max-time $server_response_maxtime ";
796 $flags .= "--silent ";
797 $flags .= "--verbose ";
798 $flags .= "--globoff ";
800 $flags .= "\"$proto://$ip:$port/verifiedserver\"";
802 my $cmd = "$VCURL $flags 2>$verifylog";
804 # check if this is our server running on this port:
805 logmsg "RUN: $cmd\n" if($verbose);
806 my @data = runclientoutput($cmd);
808 my $res = $? >> 8; # rotate the result
810 logmsg "RUN: curl command died with a coredump\n";
814 foreach my $line (@data) {
815 if($line =~ /WE ROOLZ: (\d+)/) {
816 # this is our test server with a known pid!
821 if($pid <= 0 && @data && $data[0]) {
822 # this is not a known server
823 logmsg "RUN: Unknown server on our $server port: $port\n";
826 # we can/should use the time it took to verify the FTP server as a measure
827 # on how fast/slow this host/FTP is.
828 my $took = int(0.5+time()-$time);
831 logmsg "RUN: Verifying our test $server server took $took seconds\n";
833 $ftpchecktime = $took>=1?$took:1; # make sure it never is below 1
838 #######################################################################
839 # Verify that the server that runs on $ip, $port is our server. This also
840 # implies that we can speak with it, as there might be occasions when the
841 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
842 # assign requested address")
845 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
846 my $server = servername_id($proto, $ipvnum, $idnum);
849 my $verifyout = "$LOGDIR/".
850 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
851 unlink($verifyout) if(-f $verifyout);
853 my $verifylog = "$LOGDIR/".
854 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
855 unlink($verifylog) if(-f $verifylog);
857 my $flags = "--max-time $server_response_maxtime ";
858 $flags .= "--output $verifyout ";
859 $flags .= "--silent ";
860 $flags .= "--verbose ";
861 $flags .= "--globoff ";
862 # currently verification is done using http
863 $flags .= "\"http://$ip:$port/verifiedserver\"";
865 my $cmd = "$VCURL $flags 2>$verifylog";
867 # verify if our/any server is running on this port
868 logmsg "RUN: $cmd\n" if($verbose);
869 my $res = runclient($cmd);
871 $res >>= 8; # rotate the result
873 logmsg "RUN: curl command died with a coredump\n";
877 if($res && $verbose) {
878 logmsg "RUN: curl command returned $res\n";
879 if(open(FILE, "<$verifylog")) {
880 while(my $string = <FILE>) {
881 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
888 if(open(FILE, "<$verifyout")) {
889 while(my $string = <FILE>) {
891 last; # only want first line
896 if($data && ($data =~ /RTSP_SERVER WE ROOLZ: (\d+)/)) {
900 # curl: (6) Couldn't resolve host '::1'
901 logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
904 elsif($data || ($res != 7)) {
905 logmsg "RUN: Unknown server on our $server port: $port\n";
911 #######################################################################
912 # Verify that the ssh server has written out its pidfile, recovering
913 # the pid from the file and returning it if a process with that pid is
917 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
918 my $server = servername_id($proto, $ipvnum, $idnum);
919 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
921 if(open(FILE, "<$pidfile")) {
926 # if we have a pid it is actually our ssh server,
927 # since runsshserver() unlinks previous pidfile
929 logmsg "RUN: SSH server has died after starting up\n";
938 #######################################################################
939 # Verify that we can connect to the sftp server, properly authenticate
940 # with generated config and key files and run a simple remote pwd.
943 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
944 my $server = servername_id($proto, $ipvnum, $idnum);
946 # Find out sftp client canonical file name
947 my $sftp = find_sftp();
949 logmsg "RUN: SFTP server cannot find $sftpexe\n";
952 # Find out ssh client canonical file name
953 my $ssh = find_ssh();
955 logmsg "RUN: SFTP server cannot find $sshexe\n";
958 # Connect to sftp server, authenticate and run a remote pwd
959 # command using our generated configuration and key files
960 my $cmd = "$sftp -b $sftpcmds -F $sftpconfig -S $ssh $ip > $sftplog 2>&1";
961 my $res = runclient($cmd);
962 # Search for pwd command response in log file
963 if(open(SFTPLOGFILE, "<$sftplog")) {
964 while(<SFTPLOGFILE>) {
965 if(/^Remote working directory: /) {
975 #######################################################################
976 # Verify that the non-stunnel HTTP TLS extensions capable server that runs
977 # on $ip, $port is our server. This also implies that we can speak with it,
978 # as there might be occasions when the server runs fine but we cannot talk
979 # to it ("Failed to connect to ::1: Can't assign requested address")
982 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
983 my $server = servername_id($proto, $ipvnum, $idnum);
984 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
987 my $verifyout = "$LOGDIR/".
988 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
989 unlink($verifyout) if(-f $verifyout);
991 my $verifylog = "$LOGDIR/".
992 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
993 unlink($verifylog) if(-f $verifylog);
995 my $flags = "--max-time $server_response_maxtime ";
996 $flags .= "--output $verifyout ";
997 $flags .= "--verbose ";
998 $flags .= "--globoff ";
999 $flags .= "--insecure ";
1000 $flags .= "--tlsauthtype SRP ";
1001 $flags .= "--tlsuser jsmith ";
1002 $flags .= "--tlspassword abc ";
1003 $flags .= "\"https://$ip:$port/verifiedserver\"";
1005 my $cmd = "$VCURL $flags 2>$verifylog";
1007 # verify if our/any server is running on this port
1008 logmsg "RUN: $cmd\n" if($verbose);
1009 my $res = runclient($cmd);
1011 $res >>= 8; # rotate the result
1013 logmsg "RUN: curl command died with a coredump\n";
1017 if($res && $verbose) {
1018 logmsg "RUN: curl command returned $res\n";
1019 if(open(FILE, "<$verifylog")) {
1020 while(my $string = <FILE>) {
1021 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
1028 if(open(FILE, "<$verifyout")) {
1029 while(my $string = <FILE>) {
1035 if($data && ($data =~ /GNUTLS/) && open(FILE, "<$pidfile")) {
1039 # if we have a pid it is actually our httptls server,
1040 # since runhttptlsserver() unlinks previous pidfile
1041 if(!kill(0, $pid)) {
1042 logmsg "RUN: $server server has died after starting up\n";
1051 # curl: (6) Couldn't resolve host '::1'
1052 logmsg "RUN: failed to resolve host (https://$ip:$port/verifiedserver)\n";
1055 elsif($data || ($res && ($res != 7))) {
1056 logmsg "RUN: Unknown server on our $server port: $port ($res)\n";
1062 #######################################################################
1063 # STUB for verifying socks
1066 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1067 my $server = servername_id($proto, $ipvnum, $idnum);
1068 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
1070 if(open(FILE, "<$pidfile")) {
1075 # if we have a pid it is actually our socks server,
1076 # since runsocksserver() unlinks previous pidfile
1077 if(!kill(0, $pid)) {
1078 logmsg "RUN: SOCKS server has died after starting up\n";
1087 #######################################################################
1088 # Verify that the server that runs on $ip, $port is our server.
1089 # Retry over several seconds before giving up. The ssh server in
1090 # particular can take a long time to start if it needs to generate
1091 # keys on a slow or loaded host.
1093 # Just for convenience, test harness uses 'https' and 'httptls' literals
1094 # as values for 'proto' variable in order to differentiate different
1095 # servers. 'https' literal is used for stunnel based https test servers,
1096 # and 'httptls' is used for non-stunnel https test servers.
1099 my %protofunc = ('http' => \&verifyhttp,
1100 'https' => \&verifyhttp,
1101 'rtsp' => \&verifyrtsp,
1102 'ftp' => \&verifyftp,
1103 'pop3' => \&verifyftp,
1104 'imap' => \&verifyftp,
1105 'smtp' => \&verifyftp,
1106 'ftps' => \&verifyftp,
1107 'tftp' => \&verifyftp,
1108 'ssh' => \&verifyssh,
1109 'socks' => \&verifysocks,
1110 'gopher' => \&verifyhttp,
1111 'httptls' => \&verifyhttptls);
1114 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1116 my $count = 30; # try for this many seconds
1120 my $fun = $protofunc{$proto};
1122 $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port);
1128 # a real failure, stop trying and bail out
1136 #######################################################################
1137 # Single shot server responsiveness test. This should only be used
1138 # to verify that a server present in %run hash is still functional
1140 sub responsiveserver {
1141 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1142 my $prev_verbose = $verbose;
1145 my $fun = $protofunc{$proto};
1146 my $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port);
1147 $verbose = $prev_verbose;
1150 return 1; # responsive
1153 my $srvrname = servername_str($proto, $ipvnum, $idnum);
1154 logmsg " server precheck FAILED (unresponsive $srvrname server)\n";
1158 #######################################################################
1159 # start the http server
1162 my ($proto, $verbose, $alt, $port) = @_;
1172 if($alt eq "ipv6") {
1173 # if IPv6, use a different setup
1177 elsif($alt eq "proxy") {
1178 # basically the same, but another ID
1182 $server = servername_id($proto, $ipvnum, $idnum);
1184 $pidfile = $serverpidfile{$server};
1186 # don't retry if the server doesn't work
1187 if ($doesntrun{$pidfile}) {
1191 my $pid = processexists($pidfile);
1193 stopserver($server, "$pid");
1195 unlink($pidfile) if(-f $pidfile);
1197 $srvrname = servername_str($proto, $ipvnum, $idnum);
1199 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1201 $flags .= "--fork " if($forkserver);
1202 $flags .= "--gopher " if($proto eq "gopher");
1203 $flags .= "--connect $HOSTIP " if($alt eq "proxy");
1204 $flags .= "--verbose " if($debugprotocol);
1205 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1206 $flags .= "--id $idnum " if($idnum > 1);
1207 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1209 my $cmd = "$perl $srcdir/httpserver.pl $flags";
1210 my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1212 if($httppid <= 0 || !kill(0, $httppid)) {
1214 logmsg "RUN: failed to start the $srvrname server\n";
1215 stopserver($server, "$pid2");
1216 displaylogs($testnumcheck);
1217 $doesntrun{$pidfile} = 1;
1221 # Server is up. Verify that we can speak to it.
1222 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1224 logmsg "RUN: $srvrname server failed verification\n";
1225 # failed to talk to it properly. Kill the server and return failure
1226 stopserver($server, "$httppid $pid2");
1227 displaylogs($testnumcheck);
1228 $doesntrun{$pidfile} = 1;
1234 logmsg "RUN: $srvrname server is now running PID $httppid\n";
1239 return ($httppid, $pid2);
1242 #######################################################################
1243 # start the https stunnel based server
1245 sub runhttpsserver {
1246 my ($verbose, $ipv6, $certfile) = @_;
1247 my $proto = 'https';
1248 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1249 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1261 $server = servername_id($proto, $ipvnum, $idnum);
1263 $pidfile = $serverpidfile{$server};
1265 # don't retry if the server doesn't work
1266 if ($doesntrun{$pidfile}) {
1270 my $pid = processexists($pidfile);
1272 stopserver($server, "$pid");
1274 unlink($pidfile) if(-f $pidfile);
1276 $srvrname = servername_str($proto, $ipvnum, $idnum);
1278 $certfile = 'stunnel.pem' unless($certfile);
1280 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1282 $flags .= "--verbose " if($debugprotocol);
1283 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1284 $flags .= "--id $idnum " if($idnum > 1);
1285 $flags .= "--ipv$ipvnum --proto $proto ";
1286 $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
1287 $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
1288 $flags .= "--connect $HTTPPORT --accept $HTTPSPORT";
1290 my $cmd = "$perl $srcdir/secureserver.pl $flags";
1291 my ($httpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1293 if($httpspid <= 0 || !kill(0, $httpspid)) {
1295 logmsg "RUN: failed to start the $srvrname server\n";
1296 stopserver($server, "$pid2");
1297 displaylogs($testnumcheck);
1298 $doesntrun{$pidfile} = 1;
1302 # Server is up. Verify that we can speak to it.
1303 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $HTTPSPORT);
1305 logmsg "RUN: $srvrname server failed verification\n";
1306 # failed to talk to it properly. Kill the server and return failure
1307 stopserver($server, "$httpspid $pid2");
1308 displaylogs($testnumcheck);
1309 $doesntrun{$pidfile} = 1;
1312 # Here pid3 is actually the pid returned by the unsecure-http server.
1314 $runcert{$server} = $certfile;
1317 logmsg "RUN: $srvrname server is now running PID $httpspid\n";
1322 return ($httpspid, $pid2);
1325 #######################################################################
1326 # start the non-stunnel HTTP TLS extensions capable server
1328 sub runhttptlsserver {
1329 my ($verbose, $ipv6) = @_;
1330 my $proto = "httptls";
1331 my $port = ($ipv6 && ($ipv6 =~ /6$/)) ? $HTTPTLS6PORT : $HTTPTLSPORT;
1332 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1333 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1345 $server = servername_id($proto, $ipvnum, $idnum);
1347 $pidfile = $serverpidfile{$server};
1349 # don't retry if the server doesn't work
1350 if ($doesntrun{$pidfile}) {
1354 my $pid = processexists($pidfile);
1356 stopserver($server, "$pid");
1358 unlink($pidfile) if(-f $pidfile);
1360 $srvrname = servername_str($proto, $ipvnum, $idnum);
1362 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1364 $flags .= "--http ";
1365 $flags .= "--debug 1 " if($debugprotocol);
1366 $flags .= "--port $port ";
1367 $flags .= "--srppasswd certs/srp-verifier-db ";
1368 $flags .= "--srppasswdconf certs/srp-verifier-conf";
1370 my $cmd = "$httptlssrv $flags > $logfile 2>&1";
1371 my ($httptlspid, $pid2) = startnew($cmd, $pidfile, 10, 1); # fake pidfile
1373 if($httptlspid <= 0 || !kill(0, $httptlspid)) {
1375 logmsg "RUN: failed to start the $srvrname server\n";
1376 stopserver($server, "$pid2");
1377 displaylogs($testnumcheck);
1378 $doesntrun{$pidfile} = 1;
1382 # Server is up. Verify that we can speak to it. PID is from fake pidfile
1383 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1385 logmsg "RUN: $srvrname server failed verification\n";
1386 # failed to talk to it properly. Kill the server and return failure
1387 stopserver($server, "$httptlspid $pid2");
1388 displaylogs($testnumcheck);
1389 $doesntrun{$pidfile} = 1;
1395 logmsg "RUN: $srvrname server is now running PID $httptlspid\n";
1400 return ($httptlspid, $pid2);
1403 #######################################################################
1404 # start the pingpong server (FTP, POP3, IMAP, SMTP)
1406 sub runpingpongserver {
1407 my ($proto, $id, $verbose, $ipv6) = @_;
1409 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1410 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1411 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1418 if($proto eq "ftp") {
1419 $port = ($idnum>1)?$FTP2PORT:$FTPPORT;
1422 # if IPv6, use a different setup
1426 elsif($proto eq "pop3") {
1427 $port = ($ipvnum==6) ? $POP36PORT : $POP3PORT;
1429 elsif($proto eq "imap") {
1430 $port = ($ipvnum==6) ? $IMAP6PORT : $IMAPPORT;
1432 elsif($proto eq "smtp") {
1433 $port = ($ipvnum==6) ? $SMTP6PORT : $SMTPPORT;
1436 print STDERR "Unsupported protocol $proto!!\n";
1440 $server = servername_id($proto, $ipvnum, $idnum);
1442 $pidfile = $serverpidfile{$server};
1444 # don't retry if the server doesn't work
1445 if ($doesntrun{$pidfile}) {
1449 my $pid = processexists($pidfile);
1451 stopserver($server, "$pid");
1453 unlink($pidfile) if(-f $pidfile);
1455 $srvrname = servername_str($proto, $ipvnum, $idnum);
1457 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1459 $flags .= "--verbose " if($debugprotocol);
1460 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1461 $flags .= "--srcdir \"$srcdir\" --proto $proto ";
1462 $flags .= "--id $idnum " if($idnum > 1);
1463 $flags .= "--ipv$ipvnum --port $port --addr \"$ip\"";
1465 my $cmd = "$perl $srcdir/ftpserver.pl $flags";
1466 my ($ftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1468 if($ftppid <= 0 || !kill(0, $ftppid)) {
1470 logmsg "RUN: failed to start the $srvrname server\n";
1471 stopserver($server, "$pid2");
1472 displaylogs($testnumcheck);
1473 $doesntrun{$pidfile} = 1;
1477 # Server is up. Verify that we can speak to it.
1478 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1480 logmsg "RUN: $srvrname server failed verification\n";
1481 # failed to talk to it properly. Kill the server and return failure
1482 stopserver($server, "$ftppid $pid2");
1483 displaylogs($testnumcheck);
1484 $doesntrun{$pidfile} = 1;
1491 logmsg "RUN: $srvrname server is now running PID $ftppid\n";
1496 return ($pid2, $ftppid);
1499 #######################################################################
1500 # start the ftps server (or rather, tunnel)
1503 my ($verbose, $ipv6, $certfile) = @_;
1505 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1506 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1518 $server = servername_id($proto, $ipvnum, $idnum);
1520 $pidfile = $serverpidfile{$server};
1522 # don't retry if the server doesn't work
1523 if ($doesntrun{$pidfile}) {
1527 my $pid = processexists($pidfile);
1529 stopserver($server, "$pid");
1531 unlink($pidfile) if(-f $pidfile);
1533 $srvrname = servername_str($proto, $ipvnum, $idnum);
1535 $certfile = 'stunnel.pem' unless($certfile);
1537 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1539 $flags .= "--verbose " if($debugprotocol);
1540 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1541 $flags .= "--id $idnum " if($idnum > 1);
1542 $flags .= "--ipv$ipvnum --proto $proto ";
1543 $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
1544 $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
1545 $flags .= "--connect $FTPPORT --accept $FTPSPORT";
1547 my $cmd = "$perl $srcdir/secureserver.pl $flags";
1548 my ($ftpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1550 if($ftpspid <= 0 || !kill(0, $ftpspid)) {
1552 logmsg "RUN: failed to start the $srvrname server\n";
1553 stopserver($server, "$pid2");
1554 displaylogs($testnumcheck);
1555 $doesntrun{$pidfile} = 1;
1559 # Server is up. Verify that we can speak to it.
1560 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $FTPSPORT);
1562 logmsg "RUN: $srvrname server failed verification\n";
1563 # failed to talk to it properly. Kill the server and return failure
1564 stopserver($server, "$ftpspid $pid2");
1565 displaylogs($testnumcheck);
1566 $doesntrun{$pidfile} = 1;
1569 # Here pid3 is actually the pid returned by the unsecure-ftp server.
1571 $runcert{$server} = $certfile;
1574 logmsg "RUN: $srvrname server is now running PID $ftpspid\n";
1579 return ($ftpspid, $pid2);
1582 #######################################################################
1583 # start the tftp server
1586 my ($id, $verbose, $ipv6) = @_;
1587 my $port = $TFTPPORT;
1591 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1599 # if IPv6, use a different setup
1605 $server = servername_id($proto, $ipvnum, $idnum);
1607 $pidfile = $serverpidfile{$server};
1609 # don't retry if the server doesn't work
1610 if ($doesntrun{$pidfile}) {
1614 my $pid = processexists($pidfile);
1616 stopserver($server, "$pid");
1618 unlink($pidfile) if(-f $pidfile);
1620 $srvrname = servername_str($proto, $ipvnum, $idnum);
1622 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1624 $flags .= "--verbose " if($debugprotocol);
1625 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1626 $flags .= "--id $idnum " if($idnum > 1);
1627 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1629 my $cmd = "$perl $srcdir/tftpserver.pl $flags";
1630 my ($tftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1632 if($tftppid <= 0 || !kill(0, $tftppid)) {
1634 logmsg "RUN: failed to start the $srvrname server\n";
1635 stopserver($server, "$pid2");
1636 displaylogs($testnumcheck);
1637 $doesntrun{$pidfile} = 1;
1641 # Server is up. Verify that we can speak to it.
1642 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1644 logmsg "RUN: $srvrname server failed verification\n";
1645 # failed to talk to it properly. Kill the server and return failure
1646 stopserver($server, "$tftppid $pid2");
1647 displaylogs($testnumcheck);
1648 $doesntrun{$pidfile} = 1;
1654 logmsg "RUN: $srvrname server is now running PID $tftppid\n";
1659 return ($pid2, $tftppid);
1663 #######################################################################
1664 # start the rtsp server
1667 my ($verbose, $ipv6) = @_;
1668 my $port = $RTSPPORT;
1680 # if IPv6, use a different setup
1686 $server = servername_id($proto, $ipvnum, $idnum);
1688 $pidfile = $serverpidfile{$server};
1690 # don't retry if the server doesn't work
1691 if ($doesntrun{$pidfile}) {
1695 my $pid = processexists($pidfile);
1697 stopserver($server, "$pid");
1699 unlink($pidfile) if(-f $pidfile);
1701 $srvrname = servername_str($proto, $ipvnum, $idnum);
1703 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1705 $flags .= "--verbose " if($debugprotocol);
1706 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1707 $flags .= "--id $idnum " if($idnum > 1);
1708 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1710 my $cmd = "$perl $srcdir/rtspserver.pl $flags";
1711 my ($rtsppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1713 if($rtsppid <= 0 || !kill(0, $rtsppid)) {
1715 logmsg "RUN: failed to start the $srvrname server\n";
1716 stopserver($server, "$pid2");
1717 displaylogs($testnumcheck);
1718 $doesntrun{$pidfile} = 1;
1722 # Server is up. Verify that we can speak to it.
1723 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1725 logmsg "RUN: $srvrname server failed verification\n";
1726 # failed to talk to it properly. Kill the server and return failure
1727 stopserver($server, "$rtsppid $pid2");
1728 displaylogs($testnumcheck);
1729 $doesntrun{$pidfile} = 1;
1735 logmsg "RUN: $srvrname server is now running PID $rtsppid\n";
1740 return ($rtsppid, $pid2);
1744 #######################################################################
1745 # Start the ssh (scp/sftp) server
1748 my ($id, $verbose, $ipv6) = @_;
1750 my $port = $SSHPORT;
1751 my $socksport = $SOCKSPORT;
1754 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1761 $server = servername_id($proto, $ipvnum, $idnum);
1763 $pidfile = $serverpidfile{$server};
1765 # don't retry if the server doesn't work
1766 if ($doesntrun{$pidfile}) {
1770 my $pid = processexists($pidfile);
1772 stopserver($server, "$pid");
1774 unlink($pidfile) if(-f $pidfile);
1776 $srvrname = servername_str($proto, $ipvnum, $idnum);
1778 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1780 $flags .= "--verbose " if($verbose);
1781 $flags .= "--debugprotocol " if($debugprotocol);
1782 $flags .= "--pidfile \"$pidfile\" ";
1783 $flags .= "--id $idnum " if($idnum > 1);
1784 $flags .= "--ipv$ipvnum --addr \"$ip\" ";
1785 $flags .= "--sshport $port --socksport $socksport ";
1786 $flags .= "--user \"$USER\"";
1788 my $cmd = "$perl $srcdir/sshserver.pl $flags";
1789 my ($sshpid, $pid2) = startnew($cmd, $pidfile, 60, 0);
1791 # on loaded systems sshserver start up can take longer than the timeout
1792 # passed to startnew, when this happens startnew completes without being
1793 # able to read the pidfile and consequently returns a zero pid2 above.
1795 if($sshpid <= 0 || !kill(0, $sshpid)) {
1797 logmsg "RUN: failed to start the $srvrname server\n";
1798 stopserver($server, "$pid2");
1799 $doesntrun{$pidfile} = 1;
1803 # ssh server verification allows some extra time for the server to start up
1804 # and gives us the opportunity of recovering the pid from the pidfile, when
1805 # this verification succeeds the recovered pid is assigned to pid2.
1807 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1809 logmsg "RUN: $srvrname server failed verification\n";
1810 # failed to fetch server pid. Kill the server and return failure
1811 stopserver($server, "$sshpid $pid2");
1812 $doesntrun{$pidfile} = 1;
1817 # once it is known that the ssh server is alive, sftp server verification
1818 # is performed actually connecting to it, authenticating and performing a
1819 # very simple remote command. This verification is tried only one time.
1821 $sshdlog = server_logfilename($LOGDIR, 'ssh', $ipvnum, $idnum);
1822 $sftplog = server_logfilename($LOGDIR, 'sftp', $ipvnum, $idnum);
1824 if(verifysftp('sftp', $ipvnum, $idnum, $ip, $port) < 1) {
1825 logmsg "RUN: SFTP server failed verification\n";
1826 # failed to talk to it properly. Kill the server and return failure
1828 display_sftpconfig();
1830 display_sshdconfig();
1831 stopserver($server, "$sshpid $pid2");
1832 $doesntrun{$pidfile} = 1;
1837 logmsg "RUN: $srvrname server is now running PID $pid2\n";
1840 return ($pid2, $sshpid);
1843 #######################################################################
1844 # Start the socks server
1846 sub runsocksserver {
1847 my ($id, $verbose, $ipv6) = @_;
1849 my $port = $SOCKSPORT;
1850 my $proto = 'socks';
1852 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1859 $server = servername_id($proto, $ipvnum, $idnum);
1861 $pidfile = $serverpidfile{$server};
1863 # don't retry if the server doesn't work
1864 if ($doesntrun{$pidfile}) {
1868 my $pid = processexists($pidfile);
1870 stopserver($server, "$pid");
1872 unlink($pidfile) if(-f $pidfile);
1874 $srvrname = servername_str($proto, $ipvnum, $idnum);
1876 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1878 # The ssh server must be already running
1880 logmsg "RUN: SOCKS server cannot find running SSH server\n";
1881 $doesntrun{$pidfile} = 1;
1885 # Find out ssh daemon canonical file name
1886 my $sshd = find_sshd();
1888 logmsg "RUN: SOCKS server cannot find $sshdexe\n";
1889 $doesntrun{$pidfile} = 1;
1893 # Find out ssh daemon version info
1894 ($sshdid, $sshdvernum, $sshdverstr, $sshderror) = sshversioninfo($sshd);
1896 # Not an OpenSSH or SunSSH ssh daemon
1897 logmsg "$sshderror\n" if($verbose);
1898 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
1899 $doesntrun{$pidfile} = 1;
1902 logmsg "ssh server found $sshd is $sshdverstr\n" if($verbose);
1904 # Find out ssh client canonical file name
1905 my $ssh = find_ssh();
1907 logmsg "RUN: SOCKS server cannot find $sshexe\n";
1908 $doesntrun{$pidfile} = 1;
1912 # Find out ssh client version info
1913 my ($sshid, $sshvernum, $sshverstr, $ssherror) = sshversioninfo($ssh);
1915 # Not an OpenSSH or SunSSH ssh client
1916 logmsg "$ssherror\n" if($verbose);
1917 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
1918 $doesntrun{$pidfile} = 1;
1922 # Verify minimum ssh client version
1923 if((($sshid =~ /OpenSSH/) && ($sshvernum < 299)) ||
1924 (($sshid =~ /SunSSH/) && ($sshvernum < 100))) {
1925 logmsg "ssh client found $ssh is $sshverstr\n";
1926 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
1927 $doesntrun{$pidfile} = 1;
1930 logmsg "ssh client found $ssh is $sshverstr\n" if($verbose);
1932 # Verify if ssh client and ssh daemon versions match
1933 if(($sshdid ne $sshid) || ($sshdvernum != $sshvernum)) {
1934 # Our test harness might work with slightly mismatched versions
1935 logmsg "Warning: version mismatch: sshd $sshdverstr - ssh $sshverstr\n"
1939 # Config file options for ssh client are previously set from sshserver.pl
1940 if(! -e $sshconfig) {
1941 logmsg "RUN: SOCKS server cannot find $sshconfig\n";
1942 $doesntrun{$pidfile} = 1;
1946 $sshlog = server_logfilename($LOGDIR, 'socks', $ipvnum, $idnum);
1948 # start our socks server
1949 my $cmd="$ssh -N -F $sshconfig $ip > $sshlog 2>&1";
1950 my ($sshpid, $pid2) = startnew($cmd, $pidfile, 30, 1); # fake pidfile
1952 if($sshpid <= 0 || !kill(0, $sshpid)) {
1954 logmsg "RUN: failed to start the $srvrname server\n";
1956 display_sshconfig();
1958 display_sshdconfig();
1959 stopserver($server, "$pid2");
1960 $doesntrun{$pidfile} = 1;
1964 # Ugly hack but ssh doesn't support pid files. PID is from fake pidfile.
1965 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1967 logmsg "RUN: $srvrname server failed verification\n";
1968 # failed to talk to it properly. Kill the server and return failure
1969 stopserver($server, "$sshpid $pid2");
1970 $doesntrun{$pidfile} = 1;
1976 logmsg "RUN: $srvrname server is now running PID $pid2\n";
1979 return ($pid2, $sshpid);
1982 #######################################################################
1983 # Single shot http and gopher server responsiveness test. This should only
1984 # be used to verify that a server present in %run hash is still functional
1986 sub responsive_http_server {
1987 my ($proto, $verbose, $alt, $port) = @_;
1992 if($alt eq "ipv6") {
1993 # if IPv6, use a different setup
1997 elsif($alt eq "proxy") {
2001 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2004 #######################################################################
2005 # Single shot pingpong server responsiveness test. This should only be
2006 # used to verify that a server present in %run hash is still functional
2008 sub responsive_pingpong_server {
2009 my ($proto, $id, $verbose, $ipv6) = @_;
2011 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
2012 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
2013 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
2015 if($proto eq "ftp") {
2016 $port = ($idnum>1)?$FTP2PORT:$FTPPORT;
2019 # if IPv6, use a different setup
2023 elsif($proto eq "pop3") {
2024 $port = ($ipvnum==6) ? $POP36PORT : $POP3PORT;
2026 elsif($proto eq "imap") {
2027 $port = ($ipvnum==6) ? $IMAP6PORT : $IMAPPORT;
2029 elsif($proto eq "smtp") {
2030 $port = ($ipvnum==6) ? $SMTP6PORT : $SMTPPORT;
2033 print STDERR "Unsupported protocol $proto!!\n";
2037 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2040 #######################################################################
2041 # Single shot rtsp server responsiveness test. This should only be
2042 # used to verify that a server present in %run hash is still functional
2044 sub responsive_rtsp_server {
2045 my ($verbose, $ipv6) = @_;
2046 my $port = $RTSPPORT;
2053 # if IPv6, use a different setup
2059 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2062 #######################################################################
2063 # Single shot tftp server responsiveness test. This should only be
2064 # used to verify that a server present in %run hash is still functional
2066 sub responsive_tftp_server {
2067 my ($id, $verbose, $ipv6) = @_;
2068 my $port = $TFTPPORT;
2072 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
2075 # if IPv6, use a different setup
2081 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2084 #######################################################################
2085 # Single shot non-stunnel HTTP TLS extensions capable server
2086 # responsiveness test. This should only be used to verify that a
2087 # server present in %run hash is still functional
2089 sub responsive_httptls_server {
2090 my ($verbose, $ipv6) = @_;
2091 my $proto = "httptls";
2092 my $port = ($ipv6 && ($ipv6 =~ /6$/)) ? $HTTPTLS6PORT : $HTTPTLSPORT;
2093 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
2094 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
2097 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2100 #######################################################################
2101 # Remove all files in the specified directory
2109 opendir(DIR, $dir) ||
2110 return 0; # can't open dir
2111 while($file = readdir(DIR)) {
2112 if($file !~ /^\./) {
2113 unlink("$dir/$file");
2121 #######################################################################
2122 # filter out the specified pattern from the given input file and store the
2123 # results in the given output file
2130 open(IN, "<$infile")
2133 open(OUT, ">$ofile")
2136 # logmsg "FILTER: off $filter from $infile to $ofile\n";
2147 #######################################################################
2148 # compare test results with the expected output, we might filter off
2149 # some pattern that is allowed to differ, output test results
2152 # filter off patterns _before_ this comparison!
2153 my ($subject, $firstref, $secondref)=@_;
2155 my $result = compareparts($firstref, $secondref);
2159 logmsg "\n $subject FAILED:\n";
2160 logmsg showdiff($LOGDIR, $firstref, $secondref);
2169 #######################################################################
2170 # display information about curl and the host the test suite runs on
2174 unlink($memdump); # remove this if there was one left
2183 my $curlverout="$LOGDIR/curlverout.log";
2184 my $curlvererr="$LOGDIR/curlvererr.log";
2185 my $versioncmd="$CURL --version 1>$curlverout 2>$curlvererr";
2187 unlink($curlverout);
2188 unlink($curlvererr);
2190 $versretval = runclient($versioncmd);
2193 open(VERSOUT, "<$curlverout");
2194 @version = <VERSOUT>;
2202 $curl =~ s/^(.*)(libcurl.*)/$1/g;
2205 if($curl =~ /mingw32/) {
2206 # This is a windows minw32 build, we need to translate the
2207 # given path to the "actual" windows path.
2214 # example mount output:
2215 # C:\DOCUME~1\Temp on /tmp type user (binmode,noumount)
2216 # c:\ActiveState\perl on /perl type user (binmode)
2217 # C:\msys\1.0\bin on /usr/bin type user (binmode,cygexec,noumount)
2218 # C:\msys\1.0\bin on /bin type user (binmode,cygexec,noumount)
2220 foreach $mount (@m) {
2221 if( $mount =~ /(.*) on ([^ ]*) type /) {
2222 my ($mingw, $real)=($2, $1);
2223 if($pwd =~ /^$mingw/) {
2224 # the path we got from pwd starts with the path
2225 # we found on this line in the mount output
2227 my $len = length($real);
2228 if($len > $matchlen) {
2229 # we remember the match that is the longest
2237 logmsg "Serious error, can't find our \"real\" path\n";
2240 # now prepend the prefix from the mount command to build
2242 $pwd = "$bestmatch$pwd";
2246 elsif ($curl =~ /win32/) {
2247 # Native Windows builds don't understand the
2248 # output of cygwin's pwd. It will be
2249 # something like /cygdrive/c/<some path>.
2251 # Use the cygpath utility to convert the
2252 # working directory to a Windows friendly
2253 # path. The -m option converts to use drive
2254 # letter:, but it uses / instead \. Forward
2255 # slashes (/) are easier for us. We don't
2256 # have to escape them to get them to curl
2258 chomp($pwd = `cygpath -m $pwd`);
2260 elsif ($libcurl =~ /openssl/i) {
2264 elsif ($libcurl =~ /gnutls/i) {
2268 elsif ($libcurl =~ /nss/i) {
2272 elsif ($libcurl =~ /yassl/i) {
2276 elsif ($libcurl =~ /polarssl/i) {
2280 elsif ($libcurl =~ /axtls/i) {
2284 elsif ($libcurl =~ /winssl/i) {
2289 elsif($_ =~ /^Protocols: (.*)/i) {
2290 # these are the protocols compiled in to this libcurl
2291 @protocols = split(' ', lc($1));
2293 # Generate a "proto-ipv6" version of each protocol to match the
2294 # IPv6 <server> name. This works even if IPv6 support isn't
2295 # compiled in because the <features> test will fail.
2296 push @protocols, map($_ . '-ipv6', @protocols);
2298 # 'http-proxy' is used in test cases to do CONNECT through
2299 push @protocols, 'http-proxy';
2301 # 'none' is used in test cases to mean no server
2302 push @protocols, 'none';
2304 elsif($_ =~ /^Features: (.*)/i) {
2306 if($feat =~ /TrackMemory/i) {
2307 # curl was built with --enable-curldebug (memory tracking)
2310 if($feat =~ /debug/i) {
2311 # curl was built with --enable-debug
2314 if($feat =~ /SSL/i) {
2318 if($feat =~ /Largefile/i) {
2319 # large file support
2322 if($feat =~ /IDN/i) {
2326 if($feat =~ /IPv6/i) {
2329 if($feat =~ /libz/i) {
2332 if($feat =~ /NTLM/i) {
2336 if($feat =~ /NTLM_WB/i) {
2337 # NTLM delegation to winbind daemon ntlm_auth helper enabled
2340 if($feat =~ /CharConv/i) {
2344 if($feat =~ /TLS-SRP/i) {
2348 if($feat =~ /Metalink/i) {
2354 # Test harness currently uses a non-stunnel server in order to
2355 # run HTTP TLS-SRP tests required when curl is built with https
2356 # protocol support and TLS-SRP feature enabled. For convenience
2357 # 'httptls' may be included in the test harness protocols array
2358 # to differentiate this from classic stunnel based 'https' test
2364 if($_ =~ /^https(-ipv6|)$/) {
2369 if($add_httptls && (! grep /^httptls$/, @protocols)) {
2370 push @protocols, 'httptls';
2371 push @protocols, 'httptls-ipv6';
2376 logmsg "unable to get curl's version, further details are:\n";
2377 logmsg "issued command: \n";
2378 logmsg "$versioncmd \n";
2379 if ($versretval == -1) {
2380 logmsg "command failed with: \n";
2381 logmsg "$versnoexec \n";
2383 elsif ($versretval & 127) {
2384 logmsg sprintf("command died with signal %d, and %s coredump.\n",
2385 ($versretval & 127), ($versretval & 128)?"a":"no");
2388 logmsg sprintf("command exited with value %d \n", $versretval >> 8);
2390 logmsg "contents of $curlverout: \n";
2391 displaylogcontent("$curlverout");
2392 logmsg "contents of $curlvererr: \n";
2393 displaylogcontent("$curlvererr");
2394 die "couldn't get curl's version";
2397 if(-r "../lib/curl_config.h") {
2398 open(CONF, "<../lib/curl_config.h");
2400 if($_ =~ /^\#define HAVE_GETRLIMIT/) {
2408 # client has ipv6 support
2410 # check if the HTTP server has it!
2411 my @sws = `server/sws --version`;
2412 if($sws[0] =~ /IPv6/) {
2413 # HTTP server has ipv6 support!
2418 # check if the FTP server has it!
2419 @sws = `server/sockfilt --version`;
2420 if($sws[0] =~ /IPv6/) {
2421 # FTP server has ipv6 support!
2426 if(!$curl_debug && $torture) {
2427 die "can't run torture tests since curl was not built with curldebug";
2430 $has_shared = `sh $CURLCONFIG --built-shared`;
2433 # curl doesn't list cryptographic support separately, so assume it's
2437 my $hostname=join(' ', runclientoutput("hostname"));
2438 my $hosttype=join(' ', runclientoutput("uname -a"));
2440 logmsg ("********* System characteristics ******** \n",
2443 "* Features: $feat\n",
2444 "* Host: $hostname",
2445 "* System: $hosttype");
2447 logmsg sprintf("* Server SSL: %8s", $stunnel?"ON ":"OFF");
2448 logmsg sprintf(" libcurl SSL: %s\n", $ssl_version?"ON ":"OFF");
2449 logmsg sprintf("* debug build: %8s", $debug_build?"ON ":"OFF");
2450 logmsg sprintf(" track memory: %s\n", $curl_debug?"ON ":"OFF");
2451 logmsg sprintf("* valgrind: %8s", $valgrind?"ON ":"OFF");
2452 logmsg sprintf(" HTTP IPv6 %s\n", $http_ipv6?"ON ":"OFF");
2453 logmsg sprintf("* FTP IPv6 %8s", $ftp_ipv6?"ON ":"OFF");
2454 logmsg sprintf(" Libtool lib: %s\n", $libtool?"ON ":"OFF");
2455 logmsg sprintf("* Shared build: %s\n", $has_shared);
2457 logmsg sprintf("* SSL library: %13s\n", $ssllib);
2460 logmsg "* Ports:\n";
2462 logmsg sprintf("* HTTP/%d ", $HTTPPORT);
2463 logmsg sprintf("FTP/%d ", $FTPPORT);
2464 logmsg sprintf("FTP2/%d ", $FTP2PORT);
2465 logmsg sprintf("RTSP/%d ", $RTSPPORT);
2467 logmsg sprintf("FTPS/%d ", $FTPSPORT);
2468 logmsg sprintf("HTTPS/%d ", $HTTPSPORT);
2470 logmsg sprintf("\n* TFTP/%d ", $TFTPPORT);
2472 logmsg sprintf("HTTP-IPv6/%d ", $HTTP6PORT);
2473 logmsg sprintf("RTSP-IPv6/%d ", $RTSP6PORT);
2476 logmsg sprintf("FTP-IPv6/%d ", $FTP6PORT);
2479 logmsg sprintf("TFTP-IPv6/%d ", $TFTP6PORT);
2481 logmsg sprintf("\n* GOPHER/%d ", $GOPHERPORT);
2483 logmsg sprintf("GOPHER-IPv6/%d", $GOPHERPORT);
2485 logmsg sprintf("\n* SSH/%d ", $SSHPORT);
2486 logmsg sprintf("SOCKS/%d ", $SOCKSPORT);
2487 logmsg sprintf("POP3/%d ", $POP3PORT);
2488 logmsg sprintf("IMAP/%d ", $IMAPPORT);
2489 logmsg sprintf("SMTP/%d\n", $SMTPPORT);
2491 logmsg sprintf("* POP3-IPv6/%d ", $POP36PORT);
2492 logmsg sprintf("IMAP-IPv6/%d ", $IMAP6PORT);
2493 logmsg sprintf("SMTP-IPv6/%d\n", $SMTP6PORT);
2496 logmsg sprintf("* HTTPTLS/%d ", $HTTPTLSPORT);
2498 logmsg sprintf("HTTPTLS-IPv6/%d ", $HTTPTLS6PORT);
2503 $has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys');
2505 logmsg "***************************************** \n";
2508 #######################################################################
2509 # substitute the variable stuff into either a joined up file or
2510 # a command, in either case passed by reference
2517 $$thing =~ s/%FTP6PORT/$FTP6PORT/g;
2518 $$thing =~ s/%FTP2PORT/$FTP2PORT/g;
2519 $$thing =~ s/%FTPSPORT/$FTPSPORT/g;
2520 $$thing =~ s/%FTPPORT/$FTPPORT/g;
2522 $$thing =~ s/%GOPHER6PORT/$GOPHER6PORT/g;
2523 $$thing =~ s/%GOPHERPORT/$GOPHERPORT/g;
2525 $$thing =~ s/%HTTPTLS6PORT/$HTTPTLS6PORT/g;
2526 $$thing =~ s/%HTTPTLSPORT/$HTTPTLSPORT/g;
2527 $$thing =~ s/%HTTP6PORT/$HTTP6PORT/g;
2528 $$thing =~ s/%HTTPSPORT/$HTTPSPORT/g;
2529 $$thing =~ s/%HTTPPORT/$HTTPPORT/g;
2530 $$thing =~ s/%PROXYPORT/$HTTPPROXYPORT/g;
2532 $$thing =~ s/%IMAP6PORT/$IMAP6PORT/g;
2533 $$thing =~ s/%IMAPPORT/$IMAPPORT/g;
2535 $$thing =~ s/%POP36PORT/$POP36PORT/g;
2536 $$thing =~ s/%POP3PORT/$POP3PORT/g;
2538 $$thing =~ s/%RTSP6PORT/$RTSP6PORT/g;
2539 $$thing =~ s/%RTSPPORT/$RTSPPORT/g;
2541 $$thing =~ s/%SMTP6PORT/$SMTP6PORT/g;
2542 $$thing =~ s/%SMTPPORT/$SMTPPORT/g;
2544 $$thing =~ s/%SOCKSPORT/$SOCKSPORT/g;
2545 $$thing =~ s/%SSHPORT/$SSHPORT/g;
2547 $$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
2548 $$thing =~ s/%TFTPPORT/$TFTPPORT/g;
2550 # client IP addresses
2552 $$thing =~ s/%CLIENT6IP/$CLIENT6IP/g;
2553 $$thing =~ s/%CLIENTIP/$CLIENTIP/g;
2555 # server IP addresses
2557 $$thing =~ s/%HOST6IP/$HOST6IP/g;
2558 $$thing =~ s/%HOSTIP/$HOSTIP/g;
2562 $$thing =~ s/%CURL/$CURL/g;
2563 $$thing =~ s/%PWD/$pwd/g;
2564 $$thing =~ s/%SRCDIR/$srcdir/g;
2565 $$thing =~ s/%USER/$USER/g;
2567 # The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be
2568 # used for time-out tests and that whould work on most hosts as these
2569 # adjust for the startup/check time for this particular host. We needed
2570 # to do this to make the test suite run better on very slow hosts.
2572 my $ftp2 = $ftpchecktime * 2;
2573 my $ftp3 = $ftpchecktime * 3;
2575 $$thing =~ s/%FTPTIME2/$ftp2/g;
2576 $$thing =~ s/%FTPTIME3/$ftp3/g;
2588 #######################################################################
2589 # Provide time stamps for single test skipped events
2591 sub timestampskippedevents {
2592 my $testnum = $_[0];
2594 return if((not defined($testnum)) || ($testnum < 1));
2598 if($timevrfyend{$testnum}) {
2601 elsif($timesrvrlog{$testnum}) {
2602 $timevrfyend{$testnum} = $timesrvrlog{$testnum};
2605 elsif($timetoolend{$testnum}) {
2606 $timevrfyend{$testnum} = $timetoolend{$testnum};
2607 $timesrvrlog{$testnum} = $timetoolend{$testnum};
2609 elsif($timetoolini{$testnum}) {
2610 $timevrfyend{$testnum} = $timetoolini{$testnum};
2611 $timesrvrlog{$testnum} = $timetoolini{$testnum};
2612 $timetoolend{$testnum} = $timetoolini{$testnum};
2614 elsif($timesrvrend{$testnum}) {
2615 $timevrfyend{$testnum} = $timesrvrend{$testnum};
2616 $timesrvrlog{$testnum} = $timesrvrend{$testnum};
2617 $timetoolend{$testnum} = $timesrvrend{$testnum};
2618 $timetoolini{$testnum} = $timesrvrend{$testnum};
2620 elsif($timesrvrini{$testnum}) {
2621 $timevrfyend{$testnum} = $timesrvrini{$testnum};
2622 $timesrvrlog{$testnum} = $timesrvrini{$testnum};
2623 $timetoolend{$testnum} = $timesrvrini{$testnum};
2624 $timetoolini{$testnum} = $timesrvrini{$testnum};
2625 $timesrvrend{$testnum} = $timesrvrini{$testnum};
2627 elsif($timeprepini{$testnum}) {
2628 $timevrfyend{$testnum} = $timeprepini{$testnum};
2629 $timesrvrlog{$testnum} = $timeprepini{$testnum};
2630 $timetoolend{$testnum} = $timeprepini{$testnum};
2631 $timetoolini{$testnum} = $timeprepini{$testnum};
2632 $timesrvrend{$testnum} = $timeprepini{$testnum};
2633 $timesrvrini{$testnum} = $timeprepini{$testnum};
2638 #######################################################################
2639 # Run a single specified test case
2642 my ($testnum, $count, $total)=@_;
2648 my $disablevalgrind;
2650 # copy test number to a global scope var, this allows
2651 # testnum checking when starting test harness servers.
2652 $testnumcheck = $testnum;
2654 # timestamp test preparation start
2655 $timeprepini{$testnum} = Time::HiRes::time() if($timestats);
2657 if($disttests !~ /test$testnum\W/ ) {
2658 logmsg "Warning: test$testnum not present in tests/data/Makefile.am\n";
2660 if($disabled{$testnum}) {
2661 logmsg "Warning: test$testnum is explicitly disabled\n";
2664 # load the test case file definition
2665 if(loadtest("${TESTDIR}/test${testnum}")) {
2667 # this is not a test
2668 logmsg "RUN: $testnum doesn't look like a test case\n";
2673 @what = getpart("client", "features");
2680 $feature{$f}=$f; # we require this feature
2687 elsif($f eq "OpenSSL") {
2692 elsif($f eq "GnuTLS") {
2697 elsif($f eq "NSS") {
2702 elsif($f eq "axTLS") {
2707 elsif($f eq "WinSSL") {
2712 elsif($f eq "unittest") {
2717 elsif($f eq "debug") {
2722 elsif($f eq "large_file") {
2727 elsif($f eq "idn") {
2732 elsif($f eq "ipv6") {
2737 elsif($f eq "libz") {
2742 elsif($f eq "NTLM") {
2747 elsif($f eq "NTLM_WB") {
2752 elsif($f eq "getrlimit") {
2753 if($has_getrlimit) {
2757 elsif($f eq "crypto") {
2762 elsif($f eq "TLS-SRP") {
2767 elsif($f eq "Metalink") {
2772 elsif($f eq "socks") {
2775 # See if this "feature" is in the list of supported protocols
2776 elsif (grep /^\Q$f\E$/i, @protocols) {
2780 $why = "curl lacks $f support";
2785 my @keywords = getpart("info", "keywords");
2788 for $k (@keywords) {
2790 if ($disabled_keywords{$k}) {
2791 $why = "disabled by keyword";
2792 } elsif ($enabled_keywords{$k}) {
2797 if(!$why && !$match && %enabled_keywords) {
2798 $why = "disabled by missing keyword";
2802 # test definition may instruct to (un)set environment vars
2803 # this is done this early, so that the precheck can use environment
2804 # variables and still bail out fine on errors
2806 # restore environment variables that were modified in a previous run
2807 foreach my $var (keys %oldenv) {
2808 if($oldenv{$var} eq 'notset') {
2809 delete $ENV{$var} if($ENV{$var});
2812 $ENV{$var} = $oldenv{$var};
2814 delete $oldenv{$var};
2817 # remove test server commands file before servers are started/verified
2818 unlink($FTPDCMD) if(-f $FTPDCMD);
2820 # timestamp required servers verification start
2821 $timesrvrini{$testnum} = Time::HiRes::time() if($timestats);
2824 $why = serverfortest($testnum);
2827 # timestamp required servers verification end
2828 $timesrvrend{$testnum} = Time::HiRes::time() if($timestats);
2830 my @setenv = getpart("client", "setenv");
2832 foreach my $s (@setenv) {
2835 if($s =~ /([^=]*)=(.*)/) {
2836 my ($var, $content) = ($1, $2);
2837 # remember current setting, to restore it once test runs
2838 $oldenv{$var} = ($ENV{$var})?"$ENV{$var}":'notset';
2841 delete $ENV{$var} if($ENV{$var});
2844 if($var =~ /^LD_PRELOAD/) {
2845 if(exe_ext() && (exe_ext() eq '.exe')) {
2846 # print "Skipping LD_PRELOAD due to lack of OS support\n";
2849 if($debug_build || ($has_shared ne "yes")) {
2850 # print "Skipping LD_PRELOAD due to no release shared build\n";
2854 $ENV{$var} = "$content";
2862 # Add a precheck cache. If a precheck command was already invoked
2863 # exactly like this, then use the previous result to speed up
2864 # successive test invokes!
2866 my @precheck = getpart("client", "precheck");
2868 $cmd = $precheck[0];
2872 my @p = split(/ /, $cmd);
2874 # the first word, the command, does not contain a slash so
2875 # we will scan the "improved" PATH to find the command to
2877 my $fullp = checktestcmd($p[0]);
2882 $cmd = join(" ", @p);
2885 my @o = `$cmd 2>/dev/null`;
2890 $why = "precheck command error";
2892 logmsg "prechecked $cmd\n" if($verbose);
2897 if($why && !$listonly) {
2898 # there's a problem, count it as "skipped"
2901 $teststat[$testnum]=$why; # store reason for this test case
2904 logmsg sprintf("test %03d SKIPPED: $why\n", $testnum);
2907 timestampskippedevents($testnum);
2910 logmsg sprintf("test %03d...", $testnum);
2912 # extract the reply data
2913 my @reply = getpart("reply", "data");
2914 my @replycheck = getpart("reply", "datacheck");
2917 # we use this file instead to check the final output against
2919 my %hash = getpartattr("reply", "datacheck");
2920 if($hash{'nonewline'}) {
2921 # Yes, we must cut off the final newline from the final line
2923 chomp($replycheck[$#replycheck]);
2929 # this is the valid protocol blurb curl should generate
2930 my @protocol= fixarray ( getpart("verify", "protocol") );
2932 # this is the valid protocol blurb curl should generate to a proxy
2933 my @proxyprot = fixarray ( getpart("verify", "proxy") );
2935 # redirected stdout/stderr to these files
2936 $STDOUT="$LOGDIR/stdout$testnum";
2937 $STDERR="$LOGDIR/stderr$testnum";
2939 # if this section exists, we verify that the stdout contained this:
2940 my @validstdout = fixarray ( getpart("verify", "stdout") );
2942 # if this section exists, we verify upload
2943 my @upload = getpart("verify", "upload");
2945 # if this section exists, it might be FTP server instructions:
2946 my @ftpservercmd = getpart("reply", "servercmd");
2948 my $CURLOUT="$LOGDIR/curl$testnum.out"; # curl output if not stdout
2951 my @testname= getpart("client", "name");
2954 my $name = $testname[0];
2960 timestampskippedevents($testnum);
2961 return 0; # look successful
2964 my @codepieces = getpart("client", "tool");
2968 $tool = $codepieces[0];
2972 # remove server output logfile
2978 # write the instructions to file
2979 writearray($FTPDCMD, \@ftpservercmd);
2982 # get the command line options to use
2984 ($cmd, @blaha)= getpart("client", "command");
2987 # make some nice replace operations
2988 $cmd =~ s/\n//g; # no newlines please
2989 # substitute variables in the command line
2993 # there was no command given, use something silly
3000 # create a (possibly-empty) file before starting the test
3001 my @inputfile=getpart("client", "file");
3002 my %fileattr = getpartattr("client", "file");
3003 my $filename=$fileattr{'name'};
3004 if(@inputfile || $filename) {
3006 logmsg "ERROR: section client=>file has no name attribute\n";
3007 timestampskippedevents($testnum);
3010 my $fileContent = join('', @inputfile);
3011 subVariables \$fileContent;
3012 # logmsg "DEBUG: writing file " . $filename . "\n";
3013 open(OUTFILE, ">$filename");
3014 binmode OUTFILE; # for crapage systems, use binary
3015 print OUTFILE $fileContent;
3019 my %cmdhash = getpartattr("client", "command");
3023 if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-output/)) {
3024 #We may slap on --output!
3025 if (!@validstdout) {
3026 $out=" --output $CURLOUT ";
3030 my $serverlogslocktimeout = $defserverlogslocktimeout;
3031 if($cmdhash{'timeout'}) {
3032 # test is allowed to override default server logs lock timeout
3033 if($cmdhash{'timeout'} =~ /(\d+)/) {
3034 $serverlogslocktimeout = $1 if($1 >= 0);
3038 my $postcommanddelay = $defpostcommanddelay;
3039 if($cmdhash{'delay'}) {
3040 # test is allowed to specify a delay after command is executed
3041 if($cmdhash{'delay'} =~ /(\d+)/) {
3042 $postcommanddelay = $1 if($1 > 0);
3048 my $cmdtype = $cmdhash{'type'} || "default";
3049 if($cmdtype eq "perl") {
3050 # run the command line prepended with "perl"
3057 # run curl, add --verbose for debug information output
3058 $cmd = "-1 ".$cmd if(exists $feature{"SSL"} && ($has_axtls));
3061 if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-include/)) {
3062 $inc = "--include ";
3065 $cmdargs ="$out $inc--trace-ascii log/trace$testnum --trace-time $cmd";
3068 $cmdargs = " $cmd"; # $cmd is the command line for the test file
3069 $CURLOUT = $STDOUT; # sends received data to stdout
3071 if($tool =~ /^lib/) {
3072 $CMDLINE="$LIBDIR/$tool";
3074 elsif($tool =~ /^unit/) {
3075 $CMDLINE="$UNITDIR/$tool";
3079 logmsg "The tool set in the test case for this: '$tool' does not exist\n";
3080 timestampskippedevents($testnum);
3086 my @stdintest = getpart("client", "stdin");
3089 my $stdinfile="$LOGDIR/stdin-for-$testnum";
3090 writearray($stdinfile, \@stdintest);
3092 $cmdargs .= " <$stdinfile";
3100 if($valgrind && !$disablevalgrind) {
3101 my @valgrindoption = getpart("verify", "valgrind");
3102 if((!@valgrindoption) || ($valgrindoption[0] !~ /disable/)) {
3104 my $valgrindcmd = "$valgrind ";
3105 $valgrindcmd .= "$valgrind_tool " if($valgrind_tool);
3106 $valgrindcmd .= "--leak-check=yes ";
3107 $valgrindcmd .= "--num-callers=16 ";
3108 $valgrindcmd .= "${valgrind_logfile}=$LOGDIR/valgrind$testnum";
3109 $CMDLINE = "$valgrindcmd $CMDLINE";
3113 $CMDLINE .= "$cmdargs >$STDOUT 2>$STDERR";
3116 logmsg "$CMDLINE\n";
3119 print CMDLOG "$CMDLINE\n";
3126 # Apr 2007: precommand isn't being used and could be removed
3127 my @precommand= getpart("client", "precommand");
3128 if($precommand[0]) {
3129 # this is pure perl to eval!
3130 my $code = join("", @precommand);
3133 logmsg "perl: $code\n";
3134 logmsg "precommand: $@";
3135 stopservers($verbose);
3136 timestampskippedevents($testnum);
3142 my $gdbinit = "$TESTDIR/gdbinit$testnum";
3143 open(GDBCMD, ">$LOGDIR/gdbcmd");
3144 print GDBCMD "set args $cmdargs\n";
3145 print GDBCMD "show args\n";
3146 print GDBCMD "source $gdbinit\n" if -e $gdbinit;
3150 # timestamp starting of test command
3151 $timetoolini{$testnum} = Time::HiRes::time() if($timestats);
3153 # run the command line we built
3155 $cmdres = torture($CMDLINE,
3156 "$gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
3159 my $GDBW = ($gdbxwin) ? "-w" : "";
3160 runclient("$gdb --directory libtest $DBGCURL $GDBW -x $LOGDIR/gdbcmd");
3161 $cmdres=0; # makes it always continue after a debugged run
3164 $cmdres = runclient("$CMDLINE");
3165 my $signal_num = $cmdres & 127;
3166 $dumped_core = $cmdres & 128;
3168 if(!$anyway && ($signal_num || $dumped_core)) {
3173 $cmdres = (2000 + $signal_num) if($signal_num && !$cmdres);
3177 # timestamp finishing of test command
3178 $timetoolend{$testnum} = Time::HiRes::time() if($timestats);
3182 # there's core file present now!
3188 logmsg "core dumped\n";
3190 logmsg "running gdb for post-mortem analysis:\n";
3191 open(GDBCMD, ">$LOGDIR/gdbcmd2");
3192 print GDBCMD "bt\n";
3194 runclient("$gdb --directory libtest -x $LOGDIR/gdbcmd2 -batch $DBGCURL core ");
3195 # unlink("$LOGDIR/gdbcmd2");
3199 # If a server logs advisor read lock file exists, it is an indication
3200 # that the server has not yet finished writing out all its log files,
3201 # including server request log files used for protocol verification.
3202 # So, if the lock file exists the script waits here a certain amount
3203 # of time until the server removes it, or the given time expires.
3205 if($serverlogslocktimeout) {
3206 my $lockretry = $serverlogslocktimeout * 20;
3207 while((-f $SERVERLOGS_LOCK) && $lockretry--) {
3208 select(undef, undef, undef, 0.05);
3210 if(($lockretry < 0) &&
3211 ($serverlogslocktimeout >= $defserverlogslocktimeout)) {
3212 logmsg "Warning: server logs lock timeout ",
3213 "($serverlogslocktimeout seconds) expired\n";
3217 # Test harness ssh server does not have this synchronization mechanism,
3218 # this implies that some ssh server based tests might need a small delay
3219 # once that the client command has run to avoid false test failures.
3221 # gnutls-serv also lacks this synchronization mechanism, so gnutls-serv
3222 # based tests might need a small delay once that the client command has
3223 # run to avoid false test failures.
3225 sleep($postcommanddelay) if($postcommanddelay);
3227 # timestamp removal of server logs advisor read lock
3228 $timesrvrlog{$testnum} = Time::HiRes::time() if($timestats);
3230 # test definition might instruct to stop some servers
3231 # stop also all servers relative to the given one
3233 my @killtestservers = getpart("client", "killserver");
3234 if(@killtestservers) {
3236 # All servers relative to the given one must be stopped also
3239 foreach my $server (@killtestservers) {
3241 if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
3242 # given a stunnel ssl server, also kill non-ssl underlying one
3243 push @killservers, "${1}${2}";
3245 elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|))$/) {
3246 # given a non-ssl server, also kill stunnel piggybacking one
3247 push @killservers, "${1}s${2}";
3249 elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
3250 # given a socks server, also kill ssh underlying one
3251 push @killservers, "ssh${2}";
3253 elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
3254 # given a ssh server, also kill socks piggybacking one
3255 push @killservers, "socks${2}";
3257 push @killservers, $server;
3260 # kill sockfilter processes for pingpong relative servers
3262 foreach my $server (@killservers) {
3263 if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
3265 my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
3266 my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
3267 killsockfilters($proto, $ipvnum, $idnum, $verbose);
3271 # kill server relative pids clearing them in %run hash
3274 foreach my $server (@killservers) {
3276 $pidlist .= "$run{$server} ";
3279 $runcert{$server} = 0 if($runcert{$server});
3281 killpid($verbose, $pidlist);
3283 # cleanup server pid files
3285 foreach my $server (@killservers) {
3286 my $pidfile = $serverpidfile{$server};
3287 my $pid = processexists($pidfile);
3289 logmsg "Warning: $server server unexpectedly alive\n";
3290 killpid($verbose, $pid);
3292 unlink($pidfile) if(-f $pidfile);
3296 # remove the test server commands file after each test
3297 unlink($FTPDCMD) if(-f $FTPDCMD);
3299 # run the postcheck command
3300 my @postcheck= getpart("client", "postcheck");
3302 $cmd = $postcheck[0];
3306 logmsg "postcheck $cmd\n" if($verbose);
3307 my $rc = runclient("$cmd");
3308 # Must run the postcheck command in torture mode in order
3309 # to clean up, but the result can't be relied upon.
3310 if($rc != 0 && !$torture) {
3311 logmsg " postcheck FAILED\n";
3312 # timestamp test result verification end
3313 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3319 # restore environment variables that were modified
3321 foreach my $var (keys %oldenv) {
3322 if($oldenv{$var} eq 'notset') {
3323 delete $ENV{$var} if($ENV{$var});
3326 $ENV{$var} = "$oldenv{$var}";
3331 # Skip all the verification on torture tests
3333 if(!$cmdres && !$keepoutfiles) {
3336 # timestamp test result verification end
3337 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3341 my @err = getpart("verify", "errorcode");
3342 my $errorcode = $err[0] || "0";
3347 # verify redirected stdout
3348 my @actual = loadarray($STDOUT);
3350 # variable-replace in the stdout we have from the test case file
3351 @validstdout = fixarray(@validstdout);
3353 # get all attributes
3354 my %hash = getpartattr("verify", "stdout");
3356 # get the mode attribute
3357 my $filemode=$hash{'mode'};
3358 if($filemode && ($filemode eq "text") && $has_textaware) {
3359 # text mode when running on windows: fix line endings
3360 map s/\r\n/\n/g, @actual;
3363 if($hash{'nonewline'}) {
3364 # Yes, we must cut off the final newline from the final line
3365 # of the protocol data
3366 chomp($validstdout[$#validstdout]);
3369 $res = compare("stdout", \@actual, \@validstdout);
3371 # timestamp test result verification end
3372 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3378 $ok .= "-"; # stdout not checked
3381 my %replyattr = getpartattr("reply", "data");
3382 if(!$replyattr{'nocheck'} && (@reply || $replyattr{'sendzero'})) {
3383 # verify the received data
3384 my @out = loadarray($CURLOUT);
3385 my %hash = getpartattr("reply", "data");
3386 # get the mode attribute
3387 my $filemode=$hash{'mode'};
3388 if($filemode && ($filemode eq "text") && $has_textaware) {
3389 # text mode when running on windows: fix line endings
3390 map s/\r\n/\n/g, @out;
3393 $res = compare("data", \@out, \@reply);
3395 # timestamp test result verification end
3396 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3402 $ok .= "-"; # data not checked
3406 # verify uploaded data
3407 my @out = loadarray("$LOGDIR/upload.$testnum");
3408 $res = compare("upload", \@out, \@upload);
3410 # timestamp test result verification end
3411 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3417 $ok .= "-"; # upload not checked
3421 # Verify the sent request
3422 my @out = loadarray($SERVERIN);
3424 # what to cut off from the live protocol sent by curl
3425 my @strip = getpart("verify", "strip");
3427 my @protstrip=@protocol;
3429 # check if there's any attributes on the verify/protocol section
3430 my %hash = getpartattr("verify", "protocol");
3432 if($hash{'nonewline'}) {
3433 # Yes, we must cut off the final newline from the final line
3434 # of the protocol data
3435 chomp($protstrip[$#protstrip]);
3439 # strip off all lines that match the patterns from both arrays
3441 @out = striparray( $_, \@out);
3442 @protstrip= striparray( $_, \@protstrip);
3445 # what parts to cut off from the protocol
3446 my @strippart = getpart("verify", "strippart");
3448 for $strip (@strippart) {
3455 $res = compare("protocol", \@out, \@protstrip);
3457 # timestamp test result verification end
3458 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3466 $ok .= "-"; # protocol not checked
3470 # Verify the sent proxy request
3471 my @out = loadarray($PROXYIN);
3473 # what to cut off from the live protocol sent by curl, we use the
3474 # same rules as for <protocol>
3475 my @strip = getpart("verify", "strip");
3477 my @protstrip=@proxyprot;
3479 # check if there's any attributes on the verify/protocol section
3480 my %hash = getpartattr("verify", "proxy");
3482 if($hash{'nonewline'}) {
3483 # Yes, we must cut off the final newline from the final line
3484 # of the protocol data
3485 chomp($protstrip[$#protstrip]);
3489 # strip off all lines that match the patterns from both arrays
3491 @out = striparray( $_, \@out);
3492 @protstrip= striparray( $_, \@protstrip);
3495 # what parts to cut off from the protocol
3496 my @strippart = getpart("verify", "strippart");
3498 for $strip (@strippart) {
3505 $res = compare("proxy", \@out, \@protstrip);
3507 # timestamp test result verification end
3508 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3516 $ok .= "-"; # protocol not checked
3520 for my $partsuffix (('', '1', '2', '3', '4')) {
3521 my @outfile=getpart("verify", "file".$partsuffix);
3522 if(@outfile || partexists("verify", "file".$partsuffix) ) {
3523 # we're supposed to verify a dynamically generated file!
3524 my %hash = getpartattr("verify", "file".$partsuffix);
3526 my $filename=$hash{'name'};
3528 logmsg "ERROR: section verify=>file$partsuffix ".
3529 "has no name attribute\n";
3530 stopservers($verbose);
3531 # timestamp test result verification end
3532 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3535 my @generated=loadarray($filename);
3537 # what parts to cut off from the file
3538 my @stripfile = getpart("verify", "stripfile".$partsuffix);
3540 my $filemode=$hash{'mode'};
3541 if($filemode && ($filemode eq "text") && $has_textaware) {
3542 # text mode when running on windows means adding an extra
3544 push @stripfile, "s/\r\n/\n/";
3548 for $strip (@stripfile) {
3555 @outfile = fixarray(@outfile);
3557 $res = compare("output ($filename)", \@generated, \@outfile);
3559 # timestamp test result verification end
3560 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3564 $outputok = 1; # output checked
3567 $ok .= ($outputok) ? "o" : "-"; # output checked or not
3569 # accept multiple comma-separated error codes
3570 my @splerr = split(/ *, */, $errorcode);
3572 foreach my $e (@splerr) {
3585 logmsg sprintf("\n%s returned $cmdres, when expecting %s\n",
3586 (!$tool)?"curl":$tool, $errorcode);
3588 logmsg " exit FAILED\n";
3589 # timestamp test result verification end
3590 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3596 logmsg "\n** ALERT! memory debugging with no output file?\n"
3597 if(!$cmdtype eq "perl");
3600 my @memdata=`$memanalyze $memdump`;
3604 # well it could be other memory problems as well, but
3605 # we call it leak for short here
3610 logmsg "\n** MEMORY FAILURE\n";
3612 # timestamp test result verification end
3613 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3622 $ok .= "-"; # memory not checked
3627 unless(opendir(DIR, "$LOGDIR")) {
3628 logmsg "ERROR: unable to read $LOGDIR\n";
3629 # timestamp test result verification end
3630 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3633 my @files = readdir(DIR);
3636 foreach my $file (@files) {
3637 if($file =~ /^valgrind$testnum(\..*|)$/) {
3643 logmsg "ERROR: valgrind log file missing for test $testnum\n";
3644 # timestamp test result verification end
3645 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3648 my @e = valgrindparse($srcdir, $feature{'SSL'}, "$LOGDIR/$vgfile");
3650 logmsg " valgrind ERROR ";
3652 # timestamp test result verification end
3653 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3659 if(!$short && !$disablevalgrind) {
3660 logmsg " valgrind SKIPPED\n";
3662 $ok .= "-"; # skipped
3666 $ok .= "-"; # valgrind not checked
3669 logmsg "$ok " if(!$short);
3671 my $sofar= time()-$start;
3672 my $esttotal = $sofar/$count * $total;
3673 my $estleft = $esttotal - $sofar;
3674 my $left=sprintf("remaining: %02d:%02d",
3677 logmsg sprintf("OK (%-3d out of %-3d, %s)\n", $count, $total, $left);
3679 # the test succeeded, remove all log files
3680 if(!$keepoutfiles) {
3684 # timestamp test result verification end
3685 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3690 #######################################################################
3691 # Stop all running test servers
3694 my $verbose = $_[0];
3696 # kill sockfilter processes for all pingpong servers
3698 killallsockfilters($verbose);
3700 # kill all server pids from %run hash clearing them
3703 foreach my $server (keys %run) {
3707 my $pids = $run{$server};
3708 foreach my $pid (split(' ', $pids)) {
3710 logmsg sprintf("* kill pid for %s => %d\n",
3716 $pidlist .= "$run{$server} ";
3719 $runcert{$server} = 0 if($runcert{$server});
3721 killpid($verbose, $pidlist);
3723 # cleanup all server pid files
3725 foreach my $server (keys %serverpidfile) {
3726 my $pidfile = $serverpidfile{$server};
3727 my $pid = processexists($pidfile);
3729 logmsg "Warning: $server server unexpectedly alive\n";
3730 killpid($verbose, $pid);
3732 unlink($pidfile) if(-f $pidfile);
3736 #######################################################################
3737 # startservers() starts all the named servers
3739 # Returns: string with error reason or blank for success
3745 my (@whatlist) = split(/\s+/,$_);
3746 my $what = lc($whatlist[0]);
3747 $what =~ s/[^a-z0-9-]//g;
3750 if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
3751 $certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem';
3754 if(($what eq "pop3") ||
3756 ($what eq "imap") ||
3757 ($what eq "smtp")) {
3758 if($torture && $run{$what} &&
3759 !responsive_pingpong_server($what, "", $verbose)) {
3763 ($pid, $pid2) = runpingpongserver($what, "", $verbose);
3765 return "failed starting ". uc($what) ." server";
3767 printf ("* pid $what => %d %d\n", $pid, $pid2) if($verbose);
3768 $run{$what}="$pid $pid2";
3771 elsif($what eq "ftp2") {
3772 if($torture && $run{'ftp2'} &&
3773 !responsive_pingpong_server("ftp", "2", $verbose)) {
3777 ($pid, $pid2) = runpingpongserver("ftp", "2", $verbose);
3779 return "failed starting FTP2 server";
3781 printf ("* pid ftp2 => %d %d\n", $pid, $pid2) if($verbose);
3782 $run{'ftp2'}="$pid $pid2";
3785 elsif($what eq "ftp-ipv6") {
3786 if($torture && $run{'ftp-ipv6'} &&
3787 !responsive_pingpong_server("ftp", "", $verbose, "ipv6")) {
3788 stopserver('ftp-ipv6');
3790 if(!$run{'ftp-ipv6'}) {
3791 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose, "ipv6");
3793 return "failed starting FTP-IPv6 server";
3795 logmsg sprintf("* pid ftp-ipv6 => %d %d\n", $pid,
3796 $pid2) if($verbose);
3797 $run{'ftp-ipv6'}="$pid $pid2";
3800 elsif($what eq "gopher") {
3801 if($torture && $run{'gopher'} &&
3802 !responsive_http_server("gopher", $verbose, 0, $GOPHERPORT)) {
3803 stopserver('gopher');
3805 if(!$run{'gopher'}) {
3806 ($pid, $pid2) = runhttpserver("gopher", $verbose, 0,
3809 return "failed starting GOPHER server";
3811 logmsg sprintf ("* pid gopher => %d %d\n", $pid, $pid2)
3813 $run{'gopher'}="$pid $pid2";
3816 elsif($what eq "gopher-ipv6") {
3817 if($torture && $run{'gopher-ipv6'} &&
3818 !responsive_http_server("gopher", $verbose, "ipv6",
3820 stopserver('gopher-ipv6');
3822 if(!$run{'gopher-ipv6'}) {
3823 ($pid, $pid2) = runhttpserver("gopher", $verbose, "ipv6",
3826 return "failed starting GOPHER-IPv6 server";
3828 logmsg sprintf("* pid gopher-ipv6 => %d %d\n", $pid,
3829 $pid2) if($verbose);
3830 $run{'gopher-ipv6'}="$pid $pid2";
3833 elsif($what eq "http") {
3834 if($torture && $run{'http'} &&
3835 !responsive_http_server("http", $verbose, 0, $HTTPPORT)) {
3839 ($pid, $pid2) = runhttpserver("http", $verbose, 0,
3842 return "failed starting HTTP server";
3844 logmsg sprintf ("* pid http => %d %d\n", $pid, $pid2)
3846 $run{'http'}="$pid $pid2";
3849 elsif($what eq "http-proxy") {
3850 if($torture && $run{'http-proxy'} &&
3851 !responsive_http_server("http", $verbose, "proxy",
3853 stopserver('http-proxy');
3855 if(!$run{'http-proxy'}) {
3856 ($pid, $pid2) = runhttpserver("http", $verbose, "proxy",
3859 return "failed starting HTTP-proxy server";
3861 logmsg sprintf ("* pid http-proxy => %d %d\n", $pid, $pid2)
3863 $run{'http-proxy'}="$pid $pid2";
3866 elsif($what eq "http-ipv6") {
3867 if($torture && $run{'http-ipv6'} &&
3868 !responsive_http_server("http", $verbose, "IPv6", $HTTP6PORT)) {
3869 stopserver('http-ipv6');
3871 if(!$run{'http-ipv6'}) {
3872 ($pid, $pid2) = runhttpserver("http", $verbose, "ipv6",
3875 return "failed starting HTTP-IPv6 server";
3877 logmsg sprintf("* pid http-ipv6 => %d %d\n", $pid, $pid2)
3879 $run{'http-ipv6'}="$pid $pid2";
3882 elsif($what eq "rtsp") {
3883 if($torture && $run{'rtsp'} &&
3884 !responsive_rtsp_server($verbose)) {
3888 ($pid, $pid2) = runrtspserver($verbose);
3890 return "failed starting RTSP server";
3892 printf ("* pid rtsp => %d %d\n", $pid, $pid2) if($verbose);
3893 $run{'rtsp'}="$pid $pid2";
3896 elsif($what eq "rtsp-ipv6") {
3897 if($torture && $run{'rtsp-ipv6'} &&
3898 !responsive_rtsp_server($verbose, "IPv6")) {
3899 stopserver('rtsp-ipv6');
3901 if(!$run{'rtsp-ipv6'}) {
3902 ($pid, $pid2) = runrtspserver($verbose, "IPv6");
3904 return "failed starting RTSP-IPv6 server";
3906 logmsg sprintf("* pid rtsp-ipv6 => %d %d\n", $pid, $pid2)
3908 $run{'rtsp-ipv6'}="$pid $pid2";
3911 elsif($what eq "ftps") {
3913 # we can't run ftps tests without stunnel
3914 return "no stunnel";
3917 # we can't run ftps tests if libcurl is SSL-less
3918 return "curl lacks SSL support";
3920 if($runcert{'ftps'} && ($runcert{'ftps'} ne $certfile)) {
3921 # stop server when running and using a different cert
3924 if($torture && $run{'ftp'} &&
3925 !responsive_pingpong_server("ftp", "", $verbose)) {
3929 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose);
3931 return "failed starting FTP server";
3933 printf ("* pid ftp => %d %d\n", $pid, $pid2) if($verbose);
3934 $run{'ftp'}="$pid $pid2";
3937 ($pid, $pid2) = runftpsserver($verbose, "", $certfile);
3939 return "failed starting FTPS server (stunnel)";
3941 logmsg sprintf("* pid ftps => %d %d\n", $pid, $pid2)
3943 $run{'ftps'}="$pid $pid2";
3946 elsif($what eq "file") {
3947 # we support it but have no server!
3949 elsif($what eq "https") {
3951 # we can't run https tests without stunnel
3952 return "no stunnel";
3955 # we can't run https tests if libcurl is SSL-less
3956 return "curl lacks SSL support";
3958 if($runcert{'https'} && ($runcert{'https'} ne $certfile)) {
3959 # stop server when running and using a different cert
3960 stopserver('https');
3962 if($torture && $run{'http'} &&
3963 !responsive_http_server("http", $verbose, 0, $HTTPPORT)) {
3967 ($pid, $pid2) = runhttpserver("http", $verbose, 0,
3970 return "failed starting HTTP server";
3972 printf ("* pid http => %d %d\n", $pid, $pid2) if($verbose);
3973 $run{'http'}="$pid $pid2";
3975 if(!$run{'https'}) {
3976 ($pid, $pid2) = runhttpsserver($verbose, "", $certfile);
3978 return "failed starting HTTPS server (stunnel)";
3980 logmsg sprintf("* pid https => %d %d\n", $pid, $pid2)
3982 $run{'https'}="$pid $pid2";
3985 elsif($what eq "httptls") {
3987 # for now, we can't run http TLS-EXT tests without gnutls-serv
3988 return "no gnutls-serv";
3990 if($torture && $run{'httptls'} &&
3991 !responsive_httptls_server($verbose, "IPv4")) {
3992 stopserver('httptls');
3994 if(!$run{'httptls'}) {
3995 ($pid, $pid2) = runhttptlsserver($verbose, "IPv4");
3997 return "failed starting HTTPTLS server (gnutls-serv)";
3999 logmsg sprintf("* pid httptls => %d %d\n", $pid, $pid2)
4001 $run{'httptls'}="$pid $pid2";
4004 elsif($what eq "httptls-ipv6") {
4006 # for now, we can't run http TLS-EXT tests without gnutls-serv
4007 return "no gnutls-serv";
4009 if($torture && $run{'httptls-ipv6'} &&
4010 !responsive_httptls_server($verbose, "IPv6")) {
4011 stopserver('httptls-ipv6');
4013 if(!$run{'httptls-ipv6'}) {
4014 ($pid, $pid2) = runhttptlsserver($verbose, "IPv6");
4016 return "failed starting HTTPTLS-IPv6 server (gnutls-serv)";
4018 logmsg sprintf("* pid httptls-ipv6 => %d %d\n", $pid, $pid2)
4020 $run{'httptls-ipv6'}="$pid $pid2";
4023 elsif($what eq "tftp") {
4024 if($torture && $run{'tftp'} &&
4025 !responsive_tftp_server("", $verbose)) {
4029 ($pid, $pid2) = runtftpserver("", $verbose);
4031 return "failed starting TFTP server";
4033 printf ("* pid tftp => %d %d\n", $pid, $pid2) if($verbose);
4034 $run{'tftp'}="$pid $pid2";
4037 elsif($what eq "tftp-ipv6") {
4038 if($torture && $run{'tftp-ipv6'} &&
4039 !responsive_tftp_server("", $verbose, "IPv6")) {
4040 stopserver('tftp-ipv6');
4042 if(!$run{'tftp-ipv6'}) {
4043 ($pid, $pid2) = runtftpserver("", $verbose, "IPv6");
4045 return "failed starting TFTP-IPv6 server";
4047 printf("* pid tftp-ipv6 => %d %d\n", $pid, $pid2) if($verbose);
4048 $run{'tftp-ipv6'}="$pid $pid2";
4051 elsif($what eq "sftp" || $what eq "scp" || $what eq "socks4" || $what eq "socks5" ) {
4053 ($pid, $pid2) = runsshserver("", $verbose);
4055 return "failed starting SSH server";
4057 printf ("* pid ssh => %d %d\n", $pid, $pid2) if($verbose);
4058 $run{'ssh'}="$pid $pid2";
4060 if($what eq "socks4" || $what eq "socks5") {
4061 if(!$run{'socks'}) {
4062 ($pid, $pid2) = runsocksserver("", $verbose);
4064 return "failed starting socks server";
4066 printf ("* pid socks => %d %d\n", $pid, $pid2) if($verbose);
4067 $run{'socks'}="$pid $pid2";
4070 if($what eq "socks5") {
4072 # Not an OpenSSH or SunSSH ssh daemon
4073 logmsg "Not OpenSSH or SunSSH; socks5 tests need at least OpenSSH 3.7\n";
4074 return "failed starting socks5 server";
4076 elsif(($sshdid =~ /OpenSSH/) && ($sshdvernum < 370)) {
4077 # Need OpenSSH 3.7 for socks5 - http://www.openssh.com/txt/release-3.7
4078 logmsg "$sshdverstr insufficient; socks5 tests need at least OpenSSH 3.7\n";
4079 return "failed starting socks5 server";
4081 elsif(($sshdid =~ /SunSSH/) && ($sshdvernum < 100)) {
4082 # Need SunSSH 1.0 for socks5
4083 logmsg "$sshdverstr insufficient; socks5 tests need at least SunSSH 1.0\n";
4084 return "failed starting socks5 server";
4088 elsif($what eq "none") {
4089 logmsg "* starts no server\n" if ($verbose);
4092 warn "we don't support a server for $what";
4093 return "no server for $what";
4099 ##############################################################################
4100 # This function makes sure the right set of server is running for the
4101 # specified test case. This is a useful design when we run single tests as not
4102 # all servers need to run then!
4104 # Returns: a string, blank if everything is fine or a reason why it failed
4109 my @what = getpart("client", "server");
4112 warn "Test case $testnum has no server(s) specified";
4113 return "no server specified";
4116 for(my $i = scalar(@what) - 1; $i >= 0; $i--) {
4117 my $srvrline = $what[$i];
4118 chomp $srvrline if($srvrline);
4119 if($srvrline =~ /^(\S+)((\s*)(.*))/) {
4120 my $server = "${1}";
4121 my $lnrest = "${2}";
4123 if($server =~ /^(httptls)(\+)(ext|srp)(\d*)(-ipv6|)$/) {
4124 $server = "${1}${4}${5}";
4125 $tlsext = uc("TLS-${3}");
4127 if(! grep /^\Q$server\E$/, @protocols) {
4128 if(substr($server,0,5) ne "socks") {
4130 return "curl lacks $tlsext support";
4133 return "curl lacks $server server support";
4137 $what[$i] = "$server$lnrest" if($tlsext);
4141 return &startservers(@what);
4144 #######################################################################
4145 # runtimestats displays test-suite run time statistics
4148 my $lasttest = $_[0];
4150 return if(not $timestats);
4152 logmsg "\nTest suite total running time breakdown per task...\n\n";
4160 my $timesrvrtot = 0.0;
4161 my $timepreptot = 0.0;
4162 my $timetooltot = 0.0;
4163 my $timelocktot = 0.0;
4164 my $timevrfytot = 0.0;
4165 my $timetesttot = 0.0;
4168 for my $testnum (1 .. $lasttest) {
4169 if($timesrvrini{$testnum}) {
4170 $timesrvrtot += $timesrvrend{$testnum} - $timesrvrini{$testnum};
4172 (($timetoolini{$testnum} - $timeprepini{$testnum}) -
4173 ($timesrvrend{$testnum} - $timesrvrini{$testnum}));
4174 $timetooltot += $timetoolend{$testnum} - $timetoolini{$testnum};
4175 $timelocktot += $timesrvrlog{$testnum} - $timetoolend{$testnum};
4176 $timevrfytot += $timevrfyend{$testnum} - $timesrvrlog{$testnum};
4177 $timetesttot += $timevrfyend{$testnum} - $timeprepini{$testnum};
4178 push @timesrvr, sprintf("%06.3f %04d",
4179 $timesrvrend{$testnum} - $timesrvrini{$testnum}, $testnum);
4180 push @timeprep, sprintf("%06.3f %04d",
4181 ($timetoolini{$testnum} - $timeprepini{$testnum}) -
4182 ($timesrvrend{$testnum} - $timesrvrini{$testnum}), $testnum);
4183 push @timetool, sprintf("%06.3f %04d",
4184 $timetoolend{$testnum} - $timetoolini{$testnum}, $testnum);
4185 push @timelock, sprintf("%06.3f %04d",
4186 $timesrvrlog{$testnum} - $timetoolend{$testnum}, $testnum);
4187 push @timevrfy, sprintf("%06.3f %04d",
4188 $timevrfyend{$testnum} - $timesrvrlog{$testnum}, $testnum);
4189 push @timetest, sprintf("%06.3f %04d",
4190 $timevrfyend{$testnum} - $timeprepini{$testnum}, $testnum);
4195 no warnings 'numeric';
4196 @timesrvr = sort { $b <=> $a } @timesrvr;
4197 @timeprep = sort { $b <=> $a } @timeprep;
4198 @timetool = sort { $b <=> $a } @timetool;
4199 @timelock = sort { $b <=> $a } @timelock;
4200 @timevrfy = sort { $b <=> $a } @timevrfy;
4201 @timetest = sort { $b <=> $a } @timetest;
4204 logmsg "Spent ". sprintf("%08.3f ", $timesrvrtot) .
4205 "seconds starting and verifying test harness servers.\n";
4206 logmsg "Spent ". sprintf("%08.3f ", $timepreptot) .
4207 "seconds reading definitions and doing test preparations.\n";
4208 logmsg "Spent ". sprintf("%08.3f ", $timetooltot) .
4209 "seconds actually running test tools.\n";
4210 logmsg "Spent ". sprintf("%08.3f ", $timelocktot) .
4211 "seconds awaiting server logs lock removal.\n";
4212 logmsg "Spent ". sprintf("%08.3f ", $timevrfytot) .
4213 "seconds verifying test results.\n";
4214 logmsg "Spent ". sprintf("%08.3f ", $timetesttot) .
4215 "seconds doing all of the above.\n";
4218 logmsg "\nTest server starting and verification time per test ".
4219 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4220 logmsg "-time- test\n";
4221 logmsg "------ ----\n";
4222 foreach my $txt (@timesrvr) {
4223 last if((not $fullstats) && (not $counter--));
4228 logmsg "\nTest definition reading and preparation time per test ".
4229 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4230 logmsg "-time- test\n";
4231 logmsg "------ ----\n";
4232 foreach my $txt (@timeprep) {
4233 last if((not $fullstats) && (not $counter--));
4238 logmsg "\nTest tool execution time per test ".
4239 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4240 logmsg "-time- test\n";
4241 logmsg "------ ----\n";
4242 foreach my $txt (@timetool) {
4243 last if((not $fullstats) && (not $counter--));
4248 logmsg "\nTest server logs lock removal time per test ".
4249 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4250 logmsg "-time- test\n";
4251 logmsg "------ ----\n";
4252 foreach my $txt (@timelock) {
4253 last if((not $fullstats) && (not $counter--));
4258 logmsg "\nTest results verification time per test ".
4259 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4260 logmsg "-time- test\n";
4261 logmsg "------ ----\n";
4262 foreach my $txt (@timevrfy) {
4263 last if((not $fullstats) && (not $counter--));
4268 logmsg "\nTotal time per test ".
4269 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4270 logmsg "-time- test\n";
4271 logmsg "------ ----\n";
4272 foreach my $txt (@timetest) {
4273 last if((not $fullstats) && (not $counter--));
4280 #######################################################################
4281 # Check options to this test program
4288 if ($ARGV[0] eq "-v") {
4292 elsif($ARGV[0] =~ /^-b(.*)/) {
4294 if($portno =~ s/(\d+)$//) {
4298 elsif ($ARGV[0] eq "-c") {
4299 # use this path to curl instead of default
4300 $DBGCURL=$CURL=$ARGV[1];
4303 elsif ($ARGV[0] eq "-d") {
4304 # have the servers display protocol output
4307 elsif ($ARGV[0] eq "-f") {
4308 # run fork-servers, which makes the server fork for all new
4309 # connections This is NOT what you wanna do without knowing exactly
4313 elsif ($ARGV[0] eq "-g") {
4314 # run this test with gdb
4317 elsif ($ARGV[0] eq "-gw") {
4318 # run this test with windowed gdb
4322 elsif($ARGV[0] eq "-s") {
4326 elsif($ARGV[0] eq "-n") {
4330 elsif($ARGV[0] =~ /^-t(.*)/) {
4335 if($xtra =~ s/(\d+)$//) {
4338 # we undef valgrind to make this fly in comparison
4341 elsif($ARGV[0] eq "-a") {
4342 # continue anyway, even if a test fail
4345 elsif($ARGV[0] eq "-p") {
4348 elsif($ARGV[0] eq "-l") {
4349 # lists the test case names only
4352 elsif($ARGV[0] eq "-k") {
4353 # keep stdout and stderr files after tests
4356 elsif($ARGV[0] eq "-r") {
4357 # run time statistics needs Time::HiRes
4358 if($Time::HiRes::VERSION) {
4359 keys(%timeprepini) = 1000;
4360 keys(%timesrvrini) = 1000;
4361 keys(%timesrvrend) = 1000;
4362 keys(%timetoolini) = 1000;
4363 keys(%timetoolend) = 1000;
4364 keys(%timesrvrlog) = 1000;
4365 keys(%timevrfyend) = 1000;
4370 elsif($ARGV[0] eq "-rf") {
4371 # run time statistics needs Time::HiRes
4372 if($Time::HiRes::VERSION) {
4373 keys(%timeprepini) = 1000;
4374 keys(%timesrvrini) = 1000;
4375 keys(%timesrvrend) = 1000;
4376 keys(%timetoolini) = 1000;
4377 keys(%timetoolend) = 1000;
4378 keys(%timesrvrlog) = 1000;
4379 keys(%timevrfyend) = 1000;
4384 elsif(($ARGV[0] eq "-h") || ($ARGV[0] eq "--help")) {
4387 Usage: runtests.pl [options] [test selection(s)]
4388 -a continue even if a test fails
4389 -bN use base port number N for test servers (default $base)
4390 -c path use this curl executable
4391 -d display server debug info
4392 -g run the test case with gdb
4393 -gw run the test case with gdb as a windowed application
4395 -k keep stdout and stderr files present after tests
4396 -l list all test case names/descriptions
4398 -p print log file contents when a test fails
4399 -r run time statistics
4400 -rf full run time statistics
4402 -t[N] torture (simulate memory alloc failures); N means fail Nth alloc
4404 [num] like "5 6 9" or " 5 to 22 " to run those tests only
4405 [!num] like "!5 !6 !9" to disable those tests
4406 [keyword] like "IPv6" to select only tests containing the key word
4407 [!keyword] like "!cookies" to disable any tests containing the key word
4412 elsif($ARGV[0] =~ /^(\d+)/) {
4415 for($fromnum .. $number) {
4424 elsif($ARGV[0] =~ /^to$/i) {
4425 $fromnum = $number+1;
4427 elsif($ARGV[0] =~ /^!(\d+)/) {
4431 elsif($ARGV[0] =~ /^!(.+)/) {
4432 $disabled_keywords{$1}=$1;
4434 elsif($ARGV[0] =~ /^([-[{a-zA-Z].*)/) {
4435 $enabled_keywords{$1}=$1;
4438 print "Unknown option: $ARGV[0]\n";
4444 if(@testthis && ($testthis[0] ne "")) {
4445 $TESTCASES=join(" ", @testthis);
4449 # we have found valgrind on the host, use it
4451 # verify that we can invoke it fine
4452 my $code = runclient("valgrind >/dev/null 2>&1");
4454 if(($code>>8) != 1) {
4455 #logmsg "Valgrind failure, disable it\n";
4459 # since valgrind 2.1.x, '--tool' option is mandatory
4460 # use it, if it is supported by the version installed on the system
4461 runclient("valgrind --help 2>&1 | grep -- --tool > /dev/null 2>&1");
4463 $valgrind_tool="--tool=memcheck";
4468 # A shell script. This is typically when built with libtool,
4469 $valgrind="../libtool --mode=execute $valgrind";
4473 # valgrind 3 renamed the --logfile option to --log-file!!!
4474 my $ver=join(' ', runclientoutput("valgrind --version"));
4475 # cut off all but digits and dots
4476 $ver =~ s/[^0-9.]//g;
4478 if($ver =~ /^(\d+)/) {
4481 $valgrind_logfile="--log-file";
4488 # open the executable curl and read the first 4 bytes of it
4489 open(CHECK, "<$CURL");
4491 sysread CHECK, $c, 4;
4494 # A shell script. This is typically when built with libtool,
4496 $gdb = "libtool --mode=execute gdb";
4500 $HTTPPORT = $base++; # HTTP server port
4501 $HTTPSPORT = $base++; # HTTPS (stunnel) server port
4502 $FTPPORT = $base++; # FTP server port
4503 $FTPSPORT = $base++; # FTPS (stunnel) server port
4504 $HTTP6PORT = $base++; # HTTP IPv6 server port
4505 $FTP2PORT = $base++; # FTP server 2 port
4506 $FTP6PORT = $base++; # FTP IPv6 port
4507 $TFTPPORT = $base++; # TFTP (UDP) port
4508 $TFTP6PORT = $base++; # TFTP IPv6 (UDP) port
4509 $SSHPORT = $base++; # SSH (SCP/SFTP) port
4510 $SOCKSPORT = $base++; # SOCKS port
4511 $POP3PORT = $base++; # POP3 server port
4512 $POP36PORT = $base++; # POP3 IPv6 server port
4513 $IMAPPORT = $base++; # IMAP server port
4514 $IMAP6PORT = $base++; # IMAP IPv6 server port
4515 $SMTPPORT = $base++; # SMTP server port
4516 $SMTP6PORT = $base++; # SMTP IPv6 server port
4517 $RTSPPORT = $base++; # RTSP server port
4518 $RTSP6PORT = $base++; # RTSP IPv6 server port
4519 $GOPHERPORT = $base++; # Gopher IPv4 server port
4520 $GOPHER6PORT = $base++; # Gopher IPv6 server port
4521 $HTTPTLSPORT = $base++; # HTTP TLS (non-stunnel) server port
4522 $HTTPTLS6PORT = $base++; # HTTP TLS (non-stunnel) IPv6 server port
4523 $HTTPPROXYPORT = $base++; # HTTP proxy port, when using CONNECT
4525 #######################################################################
4526 # clear and create logging directory:
4530 mkdir($LOGDIR, 0777);
4532 #######################################################################
4533 # initialize some variables
4537 init_serverpidfile_hash();
4539 #######################################################################
4540 # Output curl version and host info being tested
4547 #######################################################################
4548 # Fetch all disabled tests
4551 open(D, "<$TESTDIR/DISABLED");
4558 $disabled{$1}=$1; # disable this test number
4563 #######################################################################
4564 # If 'all' tests are requested, find out all test numbers
4567 if ( $TESTCASES eq "all") {
4568 # Get all commands and find out their test numbers
4569 opendir(DIR, $TESTDIR) || die "can't opendir $TESTDIR: $!";
4570 my @cmds = grep { /^test([0-9]+)$/ && -f "$TESTDIR/$_" } readdir(DIR);
4573 $TESTCASES=""; # start with no test cases
4575 # cut off everything but the digits
4577 $_ =~ s/[a-z\/\.]*//g;
4579 # sort the numbers from low to high
4580 foreach my $n (sort { $a <=> $b } @cmds) {
4582 # skip disabled test cases
4583 my $why = "configured as DISABLED";
4586 $teststat[$n]=$why; # store reason for this test case
4589 $TESTCASES .= " $n";
4593 #######################################################################
4594 # Start the command line log
4596 open(CMDLOG, ">$CURLLOG") ||
4597 logmsg "can't log command lines to $CURLLOG\n";
4599 #######################################################################
4601 # Display the contents of the given file. Line endings are canonicalized
4602 # and excessively long files are elided
4603 sub displaylogcontent {
4605 if(open(SINGLE, "<$file")) {
4609 while(my $string = <SINGLE>) {
4610 $string =~ s/\r\n/\n/g;
4611 $string =~ s/[\r\f\032]/\n/g;
4612 $string .= "\n" unless ($string =~ /\n$/);
4614 for my $line (split("\n", $string)) {
4615 $line =~ s/\s*\!$//;
4617 push @tail, " $line\n";
4622 $truncate = $linecount > 1000;
4628 my $tailtotal = scalar @tail;
4629 if($tailtotal > $tailshow) {
4630 $tailskip = $tailtotal - $tailshow;
4631 logmsg "=== File too long: $tailskip lines omitted here\n";
4633 for($tailskip .. $tailtotal-1) {
4643 opendir(DIR, "$LOGDIR") ||
4644 die "can't open dir: $!";
4645 my @logs = readdir(DIR);
4648 logmsg "== Contents of files in the $LOGDIR/ dir after test $testnum\n";
4649 foreach my $log (sort @logs) {
4650 if($log =~ /\.(\.|)$/) {
4651 next; # skip "." and ".."
4653 if($log =~ /^\.nfs/) {
4656 if(($log eq "memdump") || ($log eq "core")) {
4657 next; # skip "memdump" and "core"
4659 if((-d "$LOGDIR/$log") || (! -s "$LOGDIR/$log")) {
4660 next; # skip directory and empty files
4662 if(($log =~ /^stdout\d+/) && ($log !~ /^stdout$testnum/)) {
4663 next; # skip stdoutNnn of other tests
4665 if(($log =~ /^stderr\d+/) && ($log !~ /^stderr$testnum/)) {
4666 next; # skip stderrNnn of other tests
4668 if(($log =~ /^upload\d+/) && ($log !~ /^upload$testnum/)) {
4669 next; # skip uploadNnn of other tests
4671 if(($log =~ /^curl\d+\.out/) && ($log !~ /^curl$testnum\.out/)) {
4672 next; # skip curlNnn.out of other tests
4674 if(($log =~ /^test\d+\.txt/) && ($log !~ /^test$testnum\.txt/)) {
4675 next; # skip testNnn.txt of other tests
4677 if(($log =~ /^file\d+\.txt/) && ($log !~ /^file$testnum\.txt/)) {
4678 next; # skip fileNnn.txt of other tests
4680 if(($log =~ /^netrc\d+/) && ($log !~ /^netrc$testnum/)) {
4681 next; # skip netrcNnn of other tests
4683 if(($log =~ /^trace\d+/) && ($log !~ /^trace$testnum/)) {
4684 next; # skip traceNnn of other tests
4686 if(($log =~ /^valgrind\d+/) && ($log !~ /^valgrind$testnum(\..*|)$/)) {
4687 next; # skip valgrindNnn of other tests
4689 logmsg "=== Start of file $log\n";
4690 displaylogcontent("$LOGDIR/$log");
4691 logmsg "=== End of file $log\n";
4695 #######################################################################
4696 # The main test-loop
4704 my @at = split(" ", $TESTCASES);
4709 foreach $testnum (@at) {
4711 $lasttest = $testnum if($testnum > $lasttest);
4714 my $error = singletest($testnum, $count, scalar(@at));
4716 # not a test we can run
4720 $total++; # number of tests we've run
4723 $failed.= "$testnum ";
4725 # display all files in log/ in a nice way
4726 displaylogs($testnum);
4729 # a test failed, abort
4730 logmsg "\n - abort tests\n";
4735 $ok++; # successful test counter
4738 # loop for next test
4741 my $sofar = time() - $start;
4743 #######################################################################
4748 # Tests done, stop the servers
4749 stopservers($verbose);
4751 my $all = $total + $skipped;
4753 runtimestats($lasttest);
4756 logmsg sprintf("TESTDONE: $ok tests out of $total reported OK: %d%%\n",
4760 logmsg "TESTFAIL: These test cases failed: $failed\n";
4764 logmsg "TESTFAIL: No tests were performed\n";
4768 logmsg "TESTDONE: $all tests were considered during ".
4769 sprintf("%.0f", $sofar) ." seconds.\n";
4772 if($skipped && !$short) {
4774 logmsg "TESTINFO: $skipped tests were skipped due to these restraints:\n";
4776 for(keys %skipped) {
4778 printf "TESTINFO: \"%s\" %d times (", $r, $skipped{$_};
4780 # now show all test case numbers that had this reason for being
4783 for(0 .. scalar @teststat) {
4785 if($teststat[$_] && ($teststat[$_] eq $r)) {
4795 if($total && ($ok != $total)) {