2 #***************************************************************************
4 # Project ___| | | | _ \| |
6 # | (__| |_| | _ <| |___
7 # \___|\___/|_| \_\_____|
9 # Copyright (C) 1998 - 2010, 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
106 require "getpart.pm"; # array functions
107 require "valgrind.pm"; # valgrind report parser
110 my $HOSTIP="127.0.0.1"; # address on which the test server listens
111 my $HOST6IP="[::1]"; # address on which the test server listens
112 my $CLIENTIP="127.0.0.1"; # address which curl uses for incoming connections
113 my $CLIENT6IP="[::1]"; # address which curl uses for incoming connections
115 my $base = 8990; # base port number
117 my $HTTPPORT; # HTTP server port
118 my $HTTP6PORT; # HTTP IPv6 server port
119 my $HTTPSPORT; # HTTPS server port
120 my $FTPPORT; # FTP server port
121 my $FTP2PORT; # FTP server 2 port
122 my $FTPSPORT; # FTPS server port
123 my $FTP6PORT; # FTP IPv6 server port
125 my $TFTP6PORT; # TFTP
126 my $SSHPORT; # SCP/SFTP
127 my $SOCKSPORT; # SOCKS4/5 port
129 my $POP36PORT; # POP3 IPv6 server port
131 my $IMAP6PORT; # IMAP IPv6 server port
133 my $SMTP6PORT; # SMTP IPv6 server port
135 my $RTSP6PORT; # RTSP IPv6 server port
136 my $GOPHERPORT; # Gopher
137 my $GOPHER6PORT; # Gopher IPv6 server port
139 my $srcdir = $ENV{'srcdir'} || '.';
140 my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
141 my $VCURL=$CURL; # what curl binary to use to verify the servers with
142 # VCURL is handy to set to the system one when the one you
143 # just built hangs or crashes and thus prevent verification
144 my $DBGCURL=$CURL; #"../src/.libs/curl"; # alternative for debugging
146 my $TESTDIR="$srcdir/data";
147 my $LIBDIR="./libtest";
148 my $SERVERIN="$LOGDIR/server.input"; # what curl sent the server
149 my $SERVER2IN="$LOGDIR/server2.input"; # what curl sent the second server
150 my $CURLLOG="$LOGDIR/curl.log"; # all command lines run
151 my $FTPDCMD="$LOGDIR/ftpserver.cmd"; # copy ftp server instructions here
152 my $SERVERLOGS_LOCK="$LOGDIR/serverlogs.lock"; # server logs advisor read lock
153 my $CURLCONFIG="../curl-config"; # curl-config from current build
155 # Normally, all test cases should be run, but at times it is handy to
156 # simply run a particular one:
159 # To run specific test cases, set them like:
160 # $TESTCASES="1 2 3 7 8";
162 #######################################################################
163 # No variables below this point should need to be modified
166 # invoke perl like this:
167 my $perl="perl -I$srcdir";
168 my $server_response_maxtime=13;
170 my $debug_build=0; # curl built with --enable-debug
171 my $curl_debug=0; # curl built with --enable-curldebug (memory tracking)
174 # name of the file that the memory debugging creates:
175 my $memdump="$LOGDIR/memdump";
177 # the path to the script that analyzes the memory debug output file:
178 my $memanalyze="$perl $srcdir/memanalyze.pl";
180 my $pwd = getcwd(); # current working directory
184 my $ftpchecktime=1; # time it took to verify our test FTP server
186 my $stunnel = checkcmd("stunnel4") || checkcmd("stunnel");
187 my $valgrind = checktestcmd("valgrind");
188 my $valgrind_logfile="--logfile";
190 my $gdb = checktestcmd("gdb");
192 my $ssl_version; # set if libcurl is built with SSL support
193 my $large_file; # set if libcurl is built with large file support
194 my $has_idn; # set if libcurl is built with IDN support
195 my $http_ipv6; # set if HTTP server has IPv6 support
196 my $ftp_ipv6; # set if FTP server has IPv6 support
197 my $tftp_ipv6; # set if TFTP server has IPv6 support
198 my $gopher_ipv6; # set if Gopher server has IPv6 support
199 my $has_ipv6; # set if libcurl is built with IPv6 support
200 my $has_libz; # set if libcurl is built with libz support
201 my $has_getrlimit; # set if system has getrlimit()
202 my $has_ntlm; # set if libcurl is built with NTLM support
203 my $has_charconv;# set if libcurl is built with CharConv support
205 my $has_openssl; # built with a lib using an OpenSSL-like API
206 my $has_gnutls; # built with GnuTLS
207 my $has_nss; # built with NSS
208 my $has_yassl; # built with yassl
209 my $has_polarssl;# built with polarssl
211 my $has_shared; # built shared
213 my $ssllib; # name of the lib we use (for human presentation)
214 my $has_crypto; # set if libcurl is built with cryptographic support
215 my $has_textaware; # set if running on a system that has a text mode concept
216 # on files. Windows for example
217 my @protocols; # array of supported protocols
219 my $skipped=0; # number of tests skipped; reported in main loop
220 my %skipped; # skipped{reason}=counter, reasons for skip
221 my @teststat; # teststat[testnum]=reason, reasons for skip
222 my %disabled_keywords; # key words of tests to skip
223 my %enabled_keywords; # key words of tests to run
225 my $sshdid; # for socks server, ssh daemon version id
226 my $sshdvernum; # for socks server, ssh daemon version number
227 my $sshdverstr; # for socks server, ssh daemon version string
228 my $sshderror; # for socks server, ssh daemon version error
230 my $defserverlogslocktimeout = 20; # timeout to await server logs lock removal
231 my $defpostcommanddelay = 0; # delay between command and postcheck sections
233 my $timestats; # time stamping and stats generation
234 my $fullstats; # show time stats for every single test
235 my %timeprepini; # timestamp for each test preparation start
236 my %timesrvrini; # timestamp for each test required servers verification start
237 my %timesrvrend; # timestamp for each test required servers verification end
238 my %timetoolini; # timestamp for each test command run starting
239 my %timetoolend; # timestamp for each test command run stopping
240 my %timesrvrlog; # timestamp for each test server logs lock removal
241 my %timevrfyend; # timestamp for each test result verification end
243 my $testnumcheck; # test number, set in singletest sub.
246 #######################################################################
247 # variables the command line options may set
254 my $gdbthis; # run test case with gdb debugger
255 my $keepoutfiles; # keep stdout and stderr files after tests
256 my $listonly; # only list the tests
257 my $postmortem; # display detailed info about failed tests
259 my %run; # running server
260 my %doesntrun; # servers that don't work, identified by pidfile
261 my %serverpidfile;# all server pid file names, identified by server id
262 my %runcert; # cert file currently in use by an ssl running server
264 # torture test variables
269 #######################################################################
270 # logmsg is our general message logging subroutine.
278 # get the name of the current user
279 my $USER = $ENV{USER}; # Linux
281 $USER = $ENV{USERNAME}; # Windows
283 $USER = $ENV{LOGNAME}; # Some UNIX (I think)
287 # enable memory debugging if curl is compiled with it
288 $ENV{'CURL_MEMDEBUG'} = $memdump;
293 logmsg "runtests.pl received SIG$signame, exiting\n";
294 stopservers($verbose);
295 die "Somebody sent me a SIG$signame";
297 $SIG{INT} = \&catch_zap;
298 $SIG{TERM} = \&catch_zap;
300 ##########################################################################
301 # Clear all possible '*_proxy' environment variables for various protocols
302 # to prevent them to interfere with our testing!
305 foreach $protocol (('ftp', 'http', 'ftps', 'https', 'no')) {
306 my $proxy = "${protocol}_proxy";
307 # clear lowercase version
308 delete $ENV{$proxy} if($ENV{$proxy});
309 # clear uppercase version
310 delete $ENV{uc($proxy)} if($ENV{uc($proxy)});
313 # make sure we don't get affected by other variables that control our
316 delete $ENV{'SSL_CERT_DIR'} if($ENV{'SSL_CERT_DIR'});
317 delete $ENV{'SSL_CERT_PATH'} if($ENV{'SSL_CERT_PATH'});
318 delete $ENV{'CURL_CA_BUNDLE'} if($ENV{'CURL_CA_BUNDLE'});
320 #######################################################################
321 # Load serverpidfile hash with pidfile names for all possible servers.
323 sub init_serverpidfile_hash {
324 for my $proto (('ftp', 'http', 'imap', 'pop3', 'smtp')) {
325 for my $ssl (('', 's')) {
326 for my $ipvnum ((4, 6)) {
327 for my $idnum ((1, 2)) {
328 my $serv = servername_id("$proto$ssl", $ipvnum, $idnum);
329 my $pidf = server_pidfilename("$proto$ssl", $ipvnum, $idnum);
330 $serverpidfile{$serv} = $pidf;
335 for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp', 'gopher')) {
336 for my $ipvnum ((4, 6)) {
337 for my $idnum ((1, 2)) {
338 my $serv = servername_id($proto, $ipvnum, $idnum);
339 my $pidf = server_pidfilename($proto, $ipvnum, $idnum);
340 $serverpidfile{$serv} = $pidf;
346 #######################################################################
347 # Check if a given child process has just died. Reaps it if so.
350 use POSIX ":sys_wait_h";
352 if(not defined $pid || $pid <= 0) {
355 my $rc = waitpid($pid, &WNOHANG);
356 return ($rc == $pid)?1:0;
359 #######################################################################
360 # Start a new thread/process and run the given command line in there.
361 # Return the pids (yes plural) of the new child process to the parent.
364 my ($cmd, $pidfile, $timeout, $fake)=@_;
366 logmsg "startnew: $cmd\n" if ($verbose);
371 if(not defined $child) {
372 logmsg "startnew: fork() failure detected\n";
377 # Here we are the child. Run the given command.
379 # Put an "exec" in front of the command so that the child process
380 # keeps this child's process ID.
381 exec("exec $cmd") || die "Can't exec() $cmd: $!";
383 # exec() should never return back here to this process. We protect
384 # ourselves by calling die() just in case something goes really bad.
385 die "error: exec() has returned";
388 # Ugly hack but ssh client doesn't support pid files
390 if(open(OUT, ">$pidfile")) {
391 print OUT $child . "\n";
393 logmsg "startnew: $pidfile faked with pid=$child\n" if($verbose);
396 logmsg "startnew: failed to write fake $pidfile with pid=$child\n";
398 # could/should do a while connect fails sleep a bit and loop
400 if (checkdied($child)) {
401 logmsg "startnew: child process has failed to start\n" if($verbose);
406 my $count = $timeout;
408 if(-f $pidfile && -s $pidfile && open(PID, "<$pidfile")) {
411 if(($pid2 > 0) && kill(0, $pid2)) {
412 # if $pid2 is valid, then make sure this pid is alive, as
413 # otherwise it is just likely to be the _previous_ pidfile or
417 # invalidate $pid2 if not actually alive
420 if (checkdied($child)) {
421 logmsg "startnew: child process has died, server might start up\n"
423 # We can't just abort waiting for the server with a
425 # because the server might have forked and could still start
426 # up normally. Instead, just reduce the amount of time we remain
433 # Return two PIDs, the one for the child process we spawned and the one
434 # reported by the server itself (in case it forked again on its own).
435 # Both (potentially) need to be killed at the end of the test.
436 return ($child, $pid2);
440 #######################################################################
441 # Check for a command in the PATH of the test server.
445 my @paths=(split(":", $ENV{'PATH'}), "/usr/sbin", "/usr/local/sbin",
446 "/sbin", "/usr/bin", "/usr/local/bin",
447 "./libtest/.libs", "./libtest");
449 if( -x "$_/$cmd" && ! -d "$_/$cmd") {
450 # executable bit but not a directory!
456 #######################################################################
457 # Get the list of tests that the tests/data/Makefile.am knows about!
461 my @dist = `cd data && make show`;
462 $disttests = join("", @dist);
465 #######################################################################
466 # Check for a command in the PATH of the machine running curl.
470 return checkcmd($cmd);
473 #######################################################################
474 # Run the application under test and return its return code
480 # This is one way to test curl on a remote machine
481 # my $out = system("ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'");
482 # sleep 2; # time to allow the NFS server to be updated
486 #######################################################################
487 # Run the application under test and return its stdout
489 sub runclientoutput {
493 # This is one way to test curl on a remote machine
494 # my @out = `ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'`;
495 # sleep 2; # time to allow the NFS server to be updated
499 #######################################################################
500 # Memory allocation test and failure torture testing.
506 # remove memdump first to be sure we get a new nice and clean one
509 # First get URL from test server, ignore the output/result
512 logmsg " CMD: $testcmd\n" if($verbose);
514 # memanalyze -v is our friend, get the number of allocations made
516 my @out = `$memanalyze -v $memdump`;
518 if(/^Allocations: (\d+)/) {
524 logmsg " found no allocs to make fail\n";
528 logmsg " $count allocations to make fail\n";
530 for ( 1 .. $count ) {
535 if($tortalloc && ($tortalloc != $limit)) {
540 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
542 my $now = sprintf("%02d:%02d:%02d ", $hour, $min, $sec);
543 logmsg "Fail alloc no: $limit at $now\r";
546 # make the memory allocation function number $limit return failure
547 $ENV{'CURL_MEMLIMIT'} = $limit;
549 # remove memdump first to be sure we get a new nice and clean one
552 logmsg "*** Alloc number $limit is now set to fail ***\n" if($gdbthis);
559 $ret = runclient($testcmd);
561 #logmsg "$_ Returned " . $ret >> 8 . "\n";
563 # Now clear the variable again
564 delete $ENV{'CURL_MEMLIMIT'} if($ENV{'CURL_MEMLIMIT'});
567 # there's core file present now!
568 logmsg " core dumped\n";
573 # verify that it returns a proper error code, doesn't leak memory
574 # and doesn't core dump
576 logmsg " system() returned $ret\n";
580 my @memdata=`$memanalyze $memdump`;
584 # well it could be other memory problems as well, but
585 # we call it leak for short here
590 logmsg "** MEMORY FAILURE\n";
592 logmsg `$memanalyze -l $memdump`;
597 logmsg " Failed on alloc number $limit in test.\n",
598 " invoke with \"-t$limit\" to repeat this single case.\n";
599 stopservers($verbose);
604 logmsg "torture OK\n";
608 #######################################################################
609 # Stop a test server along with pids which aren't in the %run hash yet.
610 # This also stops all servers which are relative to the given one.
613 my ($server, $pidlist) = @_;
615 # kill sockfilter processes for pingpong relative server
617 if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
619 my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
620 my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
621 killsockfilters($proto, $ipvnum, $idnum, $verbose);
624 # All servers relative to the given one must be stopped also
627 if($server =~ /^(ftp|http|imap|pop3|smtp)s(.*)$/) {
628 # given an ssl server, also kill non-ssl underlying one
629 push @killservers, "${1}${2}";
631 elsif($server =~ /^(ftp|http|imap|pop3|smtp)(.*)$/) {
632 # given a non-ssl server, also kill ssl piggybacking one
633 push @killservers, "${1}s${2}";
635 elsif($server =~ /^(socks)(.*)$/) {
636 # given an socks server, also kill ssh underlying one
637 push @killservers, "ssh${2}";
639 elsif($server =~ /^(ssh)(.*)$/) {
640 # given an ssh server, also kill socks piggybacking one
641 push @killservers, "socks${2}";
643 push @killservers, $server;
645 # kill given pids and server relative ones clearing them in %run hash
647 foreach my $server (@killservers) {
649 $pidlist .= "$run{$server} ";
652 $runcert{$server} = 0 if($runcert{$server});
654 killpid($verbose, $pidlist);
656 # cleanup server pid files
658 foreach my $server (@killservers) {
659 my $pidfile = $serverpidfile{$server};
660 my $pid = processexists($pidfile);
662 logmsg "Warning: $server server unexpectedly alive\n";
663 killpid($verbose, $pid);
665 unlink($pidfile) if(-f $pidfile);
669 #######################################################################
670 # Verify that the server that runs on $ip, $port is our server. This also
671 # implies that we can speak with it, as there might be occasions when the
672 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
673 # assign requested address" #
676 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
677 my $server = servername_id($proto, $ipvnum, $idnum);
681 my $verifyout = "$LOGDIR/".
682 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
683 unlink($verifyout) if(-f $verifyout);
685 my $verifylog = "$LOGDIR/".
686 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
687 unlink($verifylog) if(-f $verifylog);
689 if($proto eq "gopher") {
694 my $flags = "--max-time $server_response_maxtime ";
695 $flags .= "--output $verifyout ";
696 $flags .= "--silent ";
697 $flags .= "--verbose ";
698 $flags .= "--globoff ";
699 $flags .= "--insecure " if($proto eq 'https');
700 $flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\"";
702 my $cmd = "$VCURL $flags 2>$verifylog";
704 # verify if our/any server is running on this port
705 logmsg "RUN: $cmd\n" if($verbose);
706 my $res = runclient($cmd);
708 $res >>= 8; # rotate the result
710 logmsg "RUN: curl command died with a coredump\n";
714 if($res && $verbose) {
715 logmsg "RUN: curl command returned $res\n";
716 if(open(FILE, "<$verifylog")) {
717 while(my $string = <FILE>) {
718 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
725 if(open(FILE, "<$verifyout")) {
726 while(my $string = <FILE>) {
728 last; # only want first line
733 if($data && ($data =~ /WE ROOLZ: (\d+)/)) {
737 # curl: (6) Couldn't resolve host '::1'
738 logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
741 elsif($data || ($res && ($res != 7))) {
742 logmsg "RUN: Unknown server on our $server port: $port ($res)\n";
748 #######################################################################
749 # Verify that the server that runs on $ip, $port is our server. This also
750 # implies that we can speak with it, as there might be occasions when the
751 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
752 # assign requested address" #
755 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
756 my $server = servername_id($proto, $ipvnum, $idnum);
761 my $verifylog = "$LOGDIR/".
762 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
763 unlink($verifylog) if(-f $verifylog);
765 if($proto eq "ftps") {
766 $extra .= "--insecure --ftp-ssl-control ";
768 elsif($proto eq "smtp") {
769 # SMTP is a bit different since it requires more options and it
771 $extra .= "--mail-rcpt verifiedserver ";
772 $extra .= "--mail-from fake ";
773 $extra .= "--upload /dev/null ";
774 $extra .= "--stderr - "; # move stderr to parse the verbose stuff
777 my $flags = "--max-time $server_response_maxtime ";
778 $flags .= "--silent ";
779 $flags .= "--verbose ";
780 $flags .= "--globoff ";
782 $flags .= "\"$proto://$ip:$port/verifiedserver\"";
784 my $cmd = "$VCURL $flags 2>$verifylog";
786 # check if this is our server running on this port:
787 logmsg "RUN: $cmd\n" if($verbose);
788 my @data = runclientoutput($cmd);
790 my $res = $? >> 8; # rotate the result
792 logmsg "RUN: curl command died with a coredump\n";
796 foreach my $line (@data) {
797 if($line =~ /WE ROOLZ: (\d+)/) {
798 # this is our test server with a known pid!
803 if($pid <= 0 && @data && $data[0]) {
804 # this is not a known server
805 logmsg "RUN: Unknown server on our $server port: $port\n";
808 # we can/should use the time it took to verify the FTP server as a measure
809 # on how fast/slow this host/FTP is.
810 my $took = int(0.5+time()-$time);
813 logmsg "RUN: Verifying our test $server server took $took seconds\n";
815 $ftpchecktime = $took>=1?$took:1; # make sure it never is below 1
820 #######################################################################
821 # Verify that the server that runs on $ip, $port is our server. This also
822 # implies that we can speak with it, as there might be occasions when the
823 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
824 # assign requested address" #
827 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
828 my $server = servername_id($proto, $ipvnum, $idnum);
831 my $verifyout = "$LOGDIR/".
832 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
833 unlink($verifyout) if(-f $verifyout);
835 my $verifylog = "$LOGDIR/".
836 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
837 unlink($verifylog) if(-f $verifylog);
839 my $flags = "--max-time $server_response_maxtime ";
840 $flags .= "--output $verifyout ";
841 $flags .= "--silent ";
842 $flags .= "--verbose ";
843 $flags .= "--globoff ";
844 # currently verification is done using http
845 $flags .= "\"http://$ip:$port/verifiedserver\"";
847 my $cmd = "$VCURL $flags 2>$verifylog";
849 # verify if our/any server is running on this port
850 logmsg "RUN: $cmd\n" if($verbose);
851 my $res = runclient($cmd);
853 $res >>= 8; # rotate the result
855 logmsg "RUN: curl command died with a coredump\n";
859 if($res && $verbose) {
860 logmsg "RUN: curl command returned $res\n";
861 if(open(FILE, "<$verifylog")) {
862 while(my $string = <FILE>) {
863 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
870 if(open(FILE, "<$verifyout")) {
871 while(my $string = <FILE>) {
873 last; # only want first line
878 if($data && ($data =~ /RTSP_SERVER WE ROOLZ: (\d+)/)) {
882 # curl: (6) Couldn't resolve host '::1'
883 logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
886 elsif($data || ($res != 7)) {
887 logmsg "RUN: Unknown server on our $server port: $port\n";
893 #######################################################################
894 # Verify that the ssh server has written out its pidfile, recovering
895 # the pid from the file and returning it if a process with that pid is
899 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
900 my $server = servername_id($proto, $ipvnum, $idnum);
901 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
903 if(open(FILE, "<$pidfile")) {
908 # if we have a pid it is actually our ssh server,
909 # since runsshserver() unlinks previous pidfile
911 logmsg "RUN: SSH server has died after starting up\n";
920 #######################################################################
921 # Verify that we can connect to the sftp server, properly authenticate
922 # with generated config and key files and run a simple remote pwd.
925 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
926 my $server = servername_id($proto, $ipvnum, $idnum);
928 # Find out sftp client canonical file name
929 my $sftp = find_sftp();
931 logmsg "RUN: SFTP server cannot find $sftpexe\n";
934 # Find out ssh client canonical file name
935 my $ssh = find_ssh();
937 logmsg "RUN: SFTP server cannot find $sshexe\n";
940 # Connect to sftp server, authenticate and run a remote pwd
941 # command using our generated configuration and key files
942 my $cmd = "$sftp -b $sftpcmds -F $sftpconfig -S $ssh $ip > $sftplog 2>&1";
943 my $res = runclient($cmd);
944 # Search for pwd command response in log file
945 if(open(SFTPLOGFILE, "<$sftplog")) {
946 while(<SFTPLOGFILE>) {
947 if(/^Remote working directory: /) {
958 #######################################################################
959 # STUB for verifying socks
962 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
963 my $server = servername_id($proto, $ipvnum, $idnum);
964 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
966 if(open(FILE, "<$pidfile")) {
971 # if we have a pid it is actually our socks server,
972 # since runsocksserver() unlinks previous pidfile
974 logmsg "RUN: SOCKS server has died after starting up\n";
983 #######################################################################
984 # Verify that the server that runs on $ip, $port is our server.
985 # Retry over several seconds before giving up. The ssh server in
986 # particular can take a long time to start if it needs to generate
987 # keys on a slow or loaded host.
990 my %protofunc = ('http' => \&verifyhttp,
991 'https' => \&verifyhttp,
992 'rtsp' => \&verifyrtsp,
993 'ftp' => \&verifyftp,
994 'pop3' => \&verifyftp,
995 'imap' => \&verifyftp,
996 'smtp' => \&verifyftp,
997 'ftps' => \&verifyftp,
998 'tftp' => \&verifyftp,
999 'ssh' => \&verifyssh,
1000 'socks' => \&verifysocks,
1001 'gopher' => \&verifyhttp);
1004 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1006 my $count = 30; # try for this many seconds
1010 my $fun = $protofunc{$proto};
1012 $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port);
1018 # a real failure, stop trying and bail out
1028 #######################################################################
1029 # start the http server
1032 my ($proto, $verbose, $ipv6, $port) = @_;
1044 # if IPv6, use a different setup
1049 $server = servername_id($proto, $ipvnum, $idnum);
1051 $pidfile = $serverpidfile{$server};
1053 # don't retry if the server doesn't work
1054 if ($doesntrun{$pidfile}) {
1058 my $pid = processexists($pidfile);
1060 stopserver($server, "$pid");
1062 unlink($pidfile) if(-f $pidfile);
1064 $srvrname = servername_str($proto, $ipvnum, $idnum);
1066 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1068 $flags .= "--fork " if($forkserver);
1069 $flags .= "--gopher " if($proto eq "gopher");
1070 $flags .= "--verbose " if($debugprotocol);
1071 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1072 $flags .= "--id $idnum " if($idnum > 1);
1073 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1075 my $cmd = "$perl $srcdir/httpserver.pl $flags";
1076 my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1078 if($httppid <= 0 || !kill(0, $httppid)) {
1080 logmsg "RUN: failed to start the $srvrname server\n";
1081 stopserver($server, "$pid2");
1082 displaylogs($testnumcheck);
1083 $doesntrun{$pidfile} = 1;
1087 # Server is up. Verify that we can speak to it.
1088 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1090 logmsg "RUN: $srvrname server failed verification\n";
1091 # failed to talk to it properly. Kill the server and return failure
1092 stopserver($server, "$httppid $pid2");
1093 displaylogs($testnumcheck);
1094 $doesntrun{$pidfile} = 1;
1100 logmsg "RUN: $srvrname server is now running PID $httppid\n";
1105 return ($httppid, $pid2);
1108 #######################################################################
1109 # start the https server (or rather, tunnel)
1111 sub runhttpsserver {
1112 my ($verbose, $ipv6, $certfile) = @_;
1113 my $proto = 'https';
1114 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1115 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1127 $server = servername_id($proto, $ipvnum, $idnum);
1129 $pidfile = $serverpidfile{$server};
1131 # don't retry if the server doesn't work
1132 if ($doesntrun{$pidfile}) {
1136 my $pid = processexists($pidfile);
1138 stopserver($server, "$pid");
1140 unlink($pidfile) if(-f $pidfile);
1142 $srvrname = servername_str($proto, $ipvnum, $idnum);
1144 $certfile = 'stunnel.pem' unless($certfile);
1146 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1148 $flags .= "--verbose " if($debugprotocol);
1149 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1150 $flags .= "--id $idnum " if($idnum > 1);
1151 $flags .= "--ipv$ipvnum --proto $proto ";
1152 $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
1153 $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
1154 $flags .= "--connect $HTTPPORT --accept $HTTPSPORT";
1156 my $cmd = "$perl $srcdir/secureserver.pl $flags";
1157 my ($httpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1159 if($httpspid <= 0 || !kill(0, $httpspid)) {
1161 logmsg "RUN: failed to start the $srvrname server\n";
1162 stopserver($server, "$pid2");
1163 displaylogs($testnumcheck);
1164 $doesntrun{$pidfile} = 1;
1168 # Server is up. Verify that we can speak to it.
1169 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $HTTPSPORT);
1171 logmsg "RUN: $srvrname server failed verification\n";
1172 # failed to talk to it properly. Kill the server and return failure
1173 stopserver($server, "$httpspid $pid2");
1174 displaylogs($testnumcheck);
1175 $doesntrun{$pidfile} = 1;
1178 # Here pid3 is actually the pid returned by the unsecure-http server.
1180 $runcert{$server} = $certfile;
1183 logmsg "RUN: $srvrname server is now running PID $httpspid\n";
1188 return ($httpspid, $pid2);
1191 #######################################################################
1192 # start the pingpong server (FTP, POP3, IMAP, SMTP)
1194 sub runpingpongserver {
1195 my ($proto, $id, $verbose, $ipv6) = @_;
1197 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1198 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1199 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1206 if($proto eq "ftp") {
1207 $port = ($idnum>1)?$FTP2PORT:$FTPPORT;
1210 # if IPv6, use a different setup
1214 elsif($proto eq "pop3") {
1215 $port = ($ipvnum==6) ? $POP36PORT : $POP3PORT;
1217 elsif($proto eq "imap") {
1218 $port = ($ipvnum==6) ? $IMAP6PORT : $IMAPPORT;
1220 elsif($proto eq "smtp") {
1221 $port = ($ipvnum==6) ? $SMTP6PORT : $SMTPPORT;
1224 print STDERR "Unsupported protocol $proto!!\n";
1228 $server = servername_id($proto, $ipvnum, $idnum);
1230 $pidfile = $serverpidfile{$server};
1232 # don't retry if the server doesn't work
1233 if ($doesntrun{$pidfile}) {
1237 my $pid = processexists($pidfile);
1239 stopserver($server, "$pid");
1241 unlink($pidfile) if(-f $pidfile);
1243 $srvrname = servername_str($proto, $ipvnum, $idnum);
1245 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1247 $flags .= "--verbose " if($debugprotocol);
1248 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1249 $flags .= "--srcdir \"$srcdir\" --proto $proto ";
1250 $flags .= "--id $idnum " if($idnum > 1);
1251 $flags .= "--ipv$ipvnum --port $port --addr \"$ip\"";
1253 my $cmd = "$perl $srcdir/ftpserver.pl $flags";
1254 my ($ftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1256 if($ftppid <= 0 || !kill(0, $ftppid)) {
1258 logmsg "RUN: failed to start the $srvrname server\n";
1259 stopserver($server, "$pid2");
1260 displaylogs($testnumcheck);
1261 $doesntrun{$pidfile} = 1;
1265 # Server is up. Verify that we can speak to it.
1266 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1268 logmsg "RUN: $srvrname server failed verification\n";
1269 # failed to talk to it properly. Kill the server and return failure
1270 stopserver($server, "$ftppid $pid2");
1271 displaylogs($testnumcheck);
1272 $doesntrun{$pidfile} = 1;
1279 logmsg "RUN: $srvrname server is now running PID $ftppid\n";
1284 return ($pid2, $ftppid);
1287 #######################################################################
1288 # start the ftps server (or rather, tunnel)
1291 my ($verbose, $ipv6, $certfile) = @_;
1293 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1294 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1306 $server = servername_id($proto, $ipvnum, $idnum);
1308 $pidfile = $serverpidfile{$server};
1310 # don't retry if the server doesn't work
1311 if ($doesntrun{$pidfile}) {
1315 my $pid = processexists($pidfile);
1317 stopserver($server, "$pid");
1319 unlink($pidfile) if(-f $pidfile);
1321 $srvrname = servername_str($proto, $ipvnum, $idnum);
1323 $certfile = 'stunnel.pem' unless($certfile);
1325 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1327 $flags .= "--verbose " if($debugprotocol);
1328 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1329 $flags .= "--id $idnum " if($idnum > 1);
1330 $flags .= "--ipv$ipvnum --proto $proto ";
1331 $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
1332 $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
1333 $flags .= "--connect $FTPPORT --accept $FTPSPORT";
1335 my $cmd = "$perl $srcdir/secureserver.pl $flags";
1336 my ($ftpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1338 if($ftpspid <= 0 || !kill(0, $ftpspid)) {
1340 logmsg "RUN: failed to start the $srvrname server\n";
1341 stopserver($server, "$pid2");
1342 displaylogs($testnumcheck);
1343 $doesntrun{$pidfile} = 1;
1347 # Server is up. Verify that we can speak to it.
1348 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $FTPSPORT);
1350 logmsg "RUN: $srvrname server failed verification\n";
1351 # failed to talk to it properly. Kill the server and return failure
1352 stopserver($server, "$ftpspid $pid2");
1353 displaylogs($testnumcheck);
1354 $doesntrun{$pidfile} = 1;
1357 # Here pid3 is actually the pid returned by the unsecure-ftp server.
1359 $runcert{$server} = $certfile;
1362 logmsg "RUN: $srvrname server is now running PID $ftpspid\n";
1367 return ($ftpspid, $pid2);
1370 #######################################################################
1371 # start the tftp server
1374 my ($id, $verbose, $ipv6) = @_;
1375 my $port = $TFTPPORT;
1379 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1387 # if IPv6, use a different setup
1393 $server = servername_id($proto, $ipvnum, $idnum);
1395 $pidfile = $serverpidfile{$server};
1397 # don't retry if the server doesn't work
1398 if ($doesntrun{$pidfile}) {
1402 my $pid = processexists($pidfile);
1404 stopserver($server, "$pid");
1406 unlink($pidfile) if(-f $pidfile);
1408 $srvrname = servername_str($proto, $ipvnum, $idnum);
1410 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1412 $flags .= "--verbose " if($debugprotocol);
1413 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1414 $flags .= "--id $idnum " if($idnum > 1);
1415 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1417 my $cmd = "$perl $srcdir/tftpserver.pl $flags";
1418 my ($tftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1420 if($tftppid <= 0 || !kill(0, $tftppid)) {
1422 logmsg "RUN: failed to start the $srvrname server\n";
1423 stopserver($server, "$pid2");
1424 displaylogs($testnumcheck);
1425 $doesntrun{$pidfile} = 1;
1429 # Server is up. Verify that we can speak to it.
1430 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1432 logmsg "RUN: $srvrname server failed verification\n";
1433 # failed to talk to it properly. Kill the server and return failure
1434 stopserver($server, "$tftppid $pid2");
1435 displaylogs($testnumcheck);
1436 $doesntrun{$pidfile} = 1;
1442 logmsg "RUN: $srvrname server is now running PID $tftppid\n";
1447 return ($pid2, $tftppid);
1451 #######################################################################
1452 # start the rtsp server
1455 my ($verbose, $ipv6) = @_;
1456 my $port = $RTSPPORT;
1468 # if IPv6, use a different setup
1474 $server = servername_id($proto, $ipvnum, $idnum);
1476 $pidfile = $serverpidfile{$server};
1478 # don't retry if the server doesn't work
1479 if ($doesntrun{$pidfile}) {
1483 my $pid = processexists($pidfile);
1485 stopserver($server, "$pid");
1487 unlink($pidfile) if(-f $pidfile);
1489 $srvrname = servername_str($proto, $ipvnum, $idnum);
1491 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1493 $flags .= "--verbose " if($debugprotocol);
1494 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1495 $flags .= "--id $idnum " if($idnum > 1);
1496 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1498 my $cmd = "$perl $srcdir/rtspserver.pl $flags";
1499 my ($rtsppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1501 if($rtsppid <= 0 || !kill(0, $rtsppid)) {
1503 logmsg "RUN: failed to start the $srvrname server\n";
1504 stopserver($server, "$pid2");
1505 displaylogs($testnumcheck);
1506 $doesntrun{$pidfile} = 1;
1510 # Server is up. Verify that we can speak to it.
1511 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1513 logmsg "RUN: $srvrname server failed verification\n";
1514 # failed to talk to it properly. Kill the server and return failure
1515 stopserver($server, "$rtsppid $pid2");
1516 displaylogs($testnumcheck);
1517 $doesntrun{$pidfile} = 1;
1523 logmsg "RUN: $srvrname server is now running PID $rtsppid\n";
1528 return ($rtsppid, $pid2);
1532 #######################################################################
1533 # Start the ssh (scp/sftp) server
1536 my ($id, $verbose, $ipv6) = @_;
1538 my $port = $SSHPORT;
1539 my $socksport = $SOCKSPORT;
1542 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1549 $server = servername_id($proto, $ipvnum, $idnum);
1551 $pidfile = $serverpidfile{$server};
1553 # don't retry if the server doesn't work
1554 if ($doesntrun{$pidfile}) {
1558 my $pid = processexists($pidfile);
1560 stopserver($server, "$pid");
1562 unlink($pidfile) if(-f $pidfile);
1564 $srvrname = servername_str($proto, $ipvnum, $idnum);
1566 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1568 $flags .= "--verbose " if($verbose);
1569 $flags .= "--debugprotocol " if($debugprotocol);
1570 $flags .= "--pidfile \"$pidfile\" ";
1571 $flags .= "--id $idnum " if($idnum > 1);
1572 $flags .= "--ipv$ipvnum --addr \"$ip\" ";
1573 $flags .= "--sshport $port --socksport $socksport ";
1574 $flags .= "--user \"$USER\"";
1576 my $cmd = "$perl $srcdir/sshserver.pl $flags";
1577 my ($sshpid, $pid2) = startnew($cmd, $pidfile, 60, 0);
1579 # on loaded systems sshserver start up can take longer than the timeout
1580 # passed to startnew, when this happens startnew completes without being
1581 # able to read the pidfile and consequently returns a zero pid2 above.
1583 if($sshpid <= 0 || !kill(0, $sshpid)) {
1585 logmsg "RUN: failed to start the $srvrname server\n";
1586 stopserver($server, "$pid2");
1587 $doesntrun{$pidfile} = 1;
1591 # ssh server verification allows some extra time for the server to start up
1592 # and gives us the opportunity of recovering the pid from the pidfile, when
1593 # this verification succeeds the recovered pid is assigned to pid2.
1595 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1597 logmsg "RUN: $srvrname server failed verification\n";
1598 # failed to fetch server pid. Kill the server and return failure
1599 stopserver($server, "$sshpid $pid2");
1600 $doesntrun{$pidfile} = 1;
1605 # once it is known that the ssh server is alive, sftp server verification
1606 # is performed actually connecting to it, authenticating and performing a
1607 # very simple remote command. This verification is tried only one time.
1609 $sshdlog = server_logfilename($LOGDIR, 'ssh', $ipvnum, $idnum);
1610 $sftplog = server_logfilename($LOGDIR, 'sftp', $ipvnum, $idnum);
1612 if(verifysftp('sftp', $ipvnum, $idnum, $ip, $port) < 1) {
1613 logmsg "RUN: SFTP server failed verification\n";
1614 # failed to talk to it properly. Kill the server and return failure
1616 display_sftpconfig();
1618 display_sshdconfig();
1619 stopserver($server, "$sshpid $pid2");
1620 $doesntrun{$pidfile} = 1;
1625 logmsg "RUN: $srvrname server is now running PID $pid2\n";
1628 return ($pid2, $sshpid);
1631 #######################################################################
1632 # Start the socks server
1634 sub runsocksserver {
1635 my ($id, $verbose, $ipv6) = @_;
1637 my $port = $SOCKSPORT;
1638 my $proto = 'socks';
1640 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1647 $server = servername_id($proto, $ipvnum, $idnum);
1649 $pidfile = $serverpidfile{$server};
1651 # don't retry if the server doesn't work
1652 if ($doesntrun{$pidfile}) {
1656 my $pid = processexists($pidfile);
1658 stopserver($server, "$pid");
1660 unlink($pidfile) if(-f $pidfile);
1662 $srvrname = servername_str($proto, $ipvnum, $idnum);
1664 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1666 # The ssh server must be already running
1668 logmsg "RUN: SOCKS server cannot find running SSH server\n";
1669 $doesntrun{$pidfile} = 1;
1673 # Find out ssh daemon canonical file name
1674 my $sshd = find_sshd();
1676 logmsg "RUN: SOCKS server cannot find $sshdexe\n";
1677 $doesntrun{$pidfile} = 1;
1681 # Find out ssh daemon version info
1682 ($sshdid, $sshdvernum, $sshdverstr, $sshderror) = sshversioninfo($sshd);
1684 # Not an OpenSSH or SunSSH ssh daemon
1685 logmsg "$sshderror\n" if($verbose);
1686 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
1687 $doesntrun{$pidfile} = 1;
1690 logmsg "ssh server found $sshd is $sshdverstr\n" if($verbose);
1692 # Find out ssh client canonical file name
1693 my $ssh = find_ssh();
1695 logmsg "RUN: SOCKS server cannot find $sshexe\n";
1696 $doesntrun{$pidfile} = 1;
1700 # Find out ssh client version info
1701 my ($sshid, $sshvernum, $sshverstr, $ssherror) = sshversioninfo($ssh);
1703 # Not an OpenSSH or SunSSH ssh client
1704 logmsg "$ssherror\n" if($verbose);
1705 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
1706 $doesntrun{$pidfile} = 1;
1710 # Verify minimum ssh client version
1711 if((($sshid =~ /OpenSSH/) && ($sshvernum < 299)) ||
1712 (($sshid =~ /SunSSH/) && ($sshvernum < 100))) {
1713 logmsg "ssh client found $ssh is $sshverstr\n";
1714 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
1715 $doesntrun{$pidfile} = 1;
1718 logmsg "ssh client found $ssh is $sshverstr\n" if($verbose);
1720 # Verify if ssh client and ssh daemon versions match
1721 if(($sshdid ne $sshid) || ($sshdvernum != $sshvernum)) {
1722 # Our test harness might work with slightly mismatched versions
1723 logmsg "Warning: version mismatch: sshd $sshdverstr - ssh $sshverstr\n"
1727 # Config file options for ssh client are previously set from sshserver.pl
1728 if(! -e $sshconfig) {
1729 logmsg "RUN: SOCKS server cannot find $sshconfig\n";
1730 $doesntrun{$pidfile} = 1;
1734 $sshlog = server_logfilename($LOGDIR, 'socks', $ipvnum, $idnum);
1736 # start our socks server
1737 my $cmd="$ssh -N -F $sshconfig $ip > $sshlog 2>&1";
1738 my ($sshpid, $pid2) = startnew($cmd, $pidfile, 30, 1);
1740 if($sshpid <= 0 || !kill(0, $sshpid)) {
1742 logmsg "RUN: failed to start the $srvrname server\n";
1744 display_sshconfig();
1746 display_sshdconfig();
1747 stopserver($server, "$pid2");
1748 $doesntrun{$pidfile} = 1;
1752 # Ugly hack but ssh doesn't support pid files
1753 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1755 logmsg "RUN: $srvrname server failed verification\n";
1756 # failed to talk to it properly. Kill the server and return failure
1757 stopserver($server, "$sshpid $pid2");
1758 $doesntrun{$pidfile} = 1;
1764 logmsg "RUN: $srvrname server is now running PID $pid2\n";
1767 return ($pid2, $sshpid);
1770 #######################################################################
1771 # Remove all files in the specified directory
1779 opendir(DIR, $dir) ||
1780 return 0; # can't open dir
1781 while($file = readdir(DIR)) {
1782 if($file !~ /^\./) {
1783 unlink("$dir/$file");
1791 #######################################################################
1792 # filter out the specified pattern from the given input file and store the
1793 # results in the given output file
1800 open(IN, "<$infile")
1803 open(OUT, ">$ofile")
1806 # logmsg "FILTER: off $filter from $infile to $ofile\n";
1817 #######################################################################
1818 # compare test results with the expected output, we might filter off
1819 # some pattern that is allowed to differ, output test results
1823 # filter off patterns _before_ this comparison!
1824 my ($subject, $firstref, $secondref)=@_;
1826 my $result = compareparts($firstref, $secondref);
1830 logmsg "\n $subject FAILED:\n";
1831 logmsg showdiff($LOGDIR, $firstref, $secondref);
1840 #######################################################################
1841 # display information about curl and the host the test suite runs on
1845 unlink($memdump); # remove this if there was one left
1854 my $curlverout="$LOGDIR/curlverout.log";
1855 my $curlvererr="$LOGDIR/curlvererr.log";
1856 my $versioncmd="$CURL --version 1>$curlverout 2>$curlvererr";
1858 unlink($curlverout);
1859 unlink($curlvererr);
1861 $versretval = runclient($versioncmd);
1864 open(VERSOUT, "<$curlverout");
1865 @version = <VERSOUT>;
1873 $curl =~ s/^(.*)(libcurl.*)/$1/g;
1876 if($curl =~ /mingw32/) {
1877 # This is a windows minw32 build, we need to translate the
1878 # given path to the "actual" windows path.
1885 # example mount output:
1886 # C:\DOCUME~1\Temp on /tmp type user (binmode,noumount)
1887 # c:\ActiveState\perl on /perl type user (binmode)
1888 # C:\msys\1.0\bin on /usr/bin type user (binmode,cygexec,noumount)
1889 # C:\msys\1.0\bin on /bin type user (binmode,cygexec,noumount)
1891 foreach $mount (@m) {
1892 if( $mount =~ /(.*) on ([^ ]*) type /) {
1893 my ($mingw, $real)=($2, $1);
1894 if($pwd =~ /^$mingw/) {
1895 # the path we got from pwd starts with the path
1896 # we found on this line in the mount output
1898 my $len = length($real);
1899 if($len > $matchlen) {
1900 # we remember the match that is the longest
1908 logmsg "Serious error, can't find our \"real\" path\n";
1911 # now prepend the prefix from the mount command to build
1913 $pwd = "$bestmatch$pwd";
1917 elsif ($curl =~ /win32/) {
1918 # Native Windows builds don't understand the
1919 # output of cygwin's pwd. It will be
1920 # something like /cygdrive/c/<some path>.
1922 # Use the cygpath utility to convert the
1923 # working directory to a Windows friendly
1924 # path. The -m option converts to use drive
1925 # letter:, but it uses / instead \. Forward
1926 # slashes (/) are easier for us. We don't
1927 # have to escape them to get them to curl
1929 chomp($pwd = `cygpath -m $pwd`);
1931 elsif ($libcurl =~ /openssl/i) {
1935 elsif ($libcurl =~ /gnutls/i) {
1939 elsif ($libcurl =~ /nss/i) {
1943 elsif ($libcurl =~ /yassl/i) {
1948 elsif ($libcurl =~ /polarssl/i) {
1954 elsif($_ =~ /^Protocols: (.*)/i) {
1955 # these are the protocols compiled in to this libcurl
1956 @protocols = split(' ', $1);
1958 # Generate a "proto-ipv6" version of each protocol to match the
1959 # IPv6 <server> name. This works even if IPv6 support isn't
1960 # compiled in because the <features> test will fail.
1961 push @protocols, map($_ . "-ipv6", @protocols);
1963 # 'none' is used in test cases to mean no server
1964 push @protocols, ('none');
1966 elsif($_ =~ /^Features: (.*)/i) {
1968 if($feat =~ /TrackMemory/i) {
1969 # curl was built with --enable-curldebug (memory tracking)
1972 if($feat =~ /debug/i) {
1973 # curl was built with --enable-debug
1975 # set the NETRC debug env
1976 $ENV{'CURL_DEBUG_NETRC'} = "$LOGDIR/netrc";
1978 if($feat =~ /SSL/i) {
1982 if($feat =~ /Largefile/i) {
1983 # large file support
1986 if($feat =~ /IDN/i) {
1990 if($feat =~ /IPv6/i) {
1993 if($feat =~ /libz/i) {
1996 if($feat =~ /NTLM/i) {
2000 if($feat =~ /CharConv/i) {
2007 logmsg "unable to get curl's version, further details are:\n";
2008 logmsg "issued command: \n";
2009 logmsg "$versioncmd \n";
2010 if ($versretval == -1) {
2011 logmsg "command failed with: \n";
2012 logmsg "$versnoexec \n";
2014 elsif ($versretval & 127) {
2015 logmsg sprintf("command died with signal %d, and %s coredump.\n",
2016 ($versretval & 127), ($versretval & 128)?"a":"no");
2019 logmsg sprintf("command exited with value %d \n", $versretval >> 8);
2021 logmsg "contents of $curlverout: \n";
2022 displaylogcontent("$curlverout");
2023 logmsg "contents of $curlvererr: \n";
2024 displaylogcontent("$curlvererr");
2025 die "couldn't get curl's version";
2028 if(-r "../lib/curl_config.h") {
2029 open(CONF, "<../lib/curl_config.h");
2031 if($_ =~ /^\#define HAVE_GETRLIMIT/) {
2039 # client has ipv6 support
2041 # check if the HTTP server has it!
2042 my @sws = `server/sws --version`;
2043 if($sws[0] =~ /IPv6/) {
2044 # HTTP server has ipv6 support!
2049 # check if the FTP server has it!
2050 @sws = `server/sockfilt --version`;
2051 if($sws[0] =~ /IPv6/) {
2052 # FTP server has ipv6 support!
2057 if(!$curl_debug && $torture) {
2058 die "can't run torture tests since curl was not built with curldebug";
2061 $has_shared = `sh $CURLCONFIG --built-shared`;
2064 # curl doesn't list cryptographic support separately, so assume it's
2068 my $hostname=join(' ', runclientoutput("hostname"));
2069 my $hosttype=join(' ', runclientoutput("uname -a"));
2071 logmsg ("********* System characteristics ******** \n",
2074 "* Features: $feat\n",
2075 "* Host: $hostname",
2076 "* System: $hosttype");
2078 logmsg sprintf("* Server SSL: %8s", $stunnel?"ON ":"OFF");
2079 logmsg sprintf(" libcurl SSL: %s\n", $ssl_version?"ON ":"OFF");
2080 logmsg sprintf("* debug build: %8s", $debug_build?"ON ":"OFF");
2081 logmsg sprintf(" track memory: %s\n", $curl_debug?"ON ":"OFF");
2082 logmsg sprintf("* valgrind: %8s", $valgrind?"ON ":"OFF");
2083 logmsg sprintf(" HTTP IPv6 %s\n", $http_ipv6?"ON ":"OFF");
2084 logmsg sprintf("* FTP IPv6 %8s", $ftp_ipv6?"ON ":"OFF");
2085 logmsg sprintf(" Libtool lib: %s\n", $libtool?"ON ":"OFF");
2086 logmsg sprintf("* Shared build: %s\n", $has_shared);
2088 logmsg sprintf("* SSL library: %13s\n", $ssllib);
2091 logmsg "* Ports:\n";
2093 logmsg sprintf("* HTTP/%d ", $HTTPPORT);
2094 logmsg sprintf("FTP/%d ", $FTPPORT);
2095 logmsg sprintf("FTP2/%d ", $FTP2PORT);
2096 logmsg sprintf("RTSP/%d ", $RTSPPORT);
2098 logmsg sprintf("FTPS/%d ", $FTPSPORT);
2099 logmsg sprintf("HTTPS/%d ", $HTTPSPORT);
2101 logmsg sprintf("\n* TFTP/%d ", $TFTPPORT);
2103 logmsg sprintf("HTTP-IPv6/%d ", $HTTP6PORT);
2104 logmsg sprintf("RTSP-IPv6/%d ", $RTSP6PORT);
2107 logmsg sprintf("FTP-IPv6/%d ", $FTP6PORT);
2110 logmsg sprintf("TFTP-IPv6/%d ", $TFTP6PORT);
2112 logmsg sprintf("\n* GOPHER/%d ", $GOPHERPORT);
2114 logmsg sprintf("GOPHER-IPv6/%d", $GOPHERPORT);
2116 logmsg sprintf("\n* SSH/%d ", $SSHPORT);
2117 logmsg sprintf("SOCKS/%d ", $SOCKSPORT);
2118 logmsg sprintf("POP3/%d ", $POP3PORT);
2119 logmsg sprintf("IMAP/%d ", $IMAPPORT);
2120 logmsg sprintf("SMTP/%d\n", $SMTPPORT);
2122 logmsg sprintf("* POP3-IPv6/%d ", $POP36PORT);
2123 logmsg sprintf("IMAP-IPv6/%d ", $IMAP6PORT);
2124 logmsg sprintf("SMTP-IPv6/%d\n", $SMTP6PORT);
2127 $has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys');
2129 logmsg "***************************************** \n";
2132 #######################################################################
2133 # substitute the variable stuff into either a joined up file or
2134 # a command, in either case passed by reference
2138 $$thing =~ s/%HOSTIP/$HOSTIP/g;
2139 $$thing =~ s/%HTTPPORT/$HTTPPORT/g;
2140 $$thing =~ s/%HOST6IP/$HOST6IP/g;
2141 $$thing =~ s/%HTTP6PORT/$HTTP6PORT/g;
2142 $$thing =~ s/%HTTPSPORT/$HTTPSPORT/g;
2143 $$thing =~ s/%FTPPORT/$FTPPORT/g;
2144 $$thing =~ s/%FTP6PORT/$FTP6PORT/g;
2145 $$thing =~ s/%FTP2PORT/$FTP2PORT/g;
2146 $$thing =~ s/%FTPSPORT/$FTPSPORT/g;
2147 $$thing =~ s/%SRCDIR/$srcdir/g;
2148 $$thing =~ s/%PWD/$pwd/g;
2149 $$thing =~ s/%TFTPPORT/$TFTPPORT/g;
2150 $$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
2151 $$thing =~ s/%SSHPORT/$SSHPORT/g;
2152 $$thing =~ s/%SOCKSPORT/$SOCKSPORT/g;
2153 $$thing =~ s/%POP3PORT/$POP3PORT/g;
2154 $$thing =~ s/%POP36PORT/$POP36PORT/g;
2155 $$thing =~ s/%IMAPPORT/$IMAPPORT/g;
2156 $$thing =~ s/%IMAP6PORT/$IMAP6PORT/g;
2157 $$thing =~ s/%SMTPPORT/$SMTPPORT/g;
2158 $$thing =~ s/%SMTP6PORT/$SMTP6PORT/g;
2159 $$thing =~ s/%CURL/$CURL/g;
2160 $$thing =~ s/%USER/$USER/g;
2161 $$thing =~ s/%CLIENTIP/$CLIENTIP/g;
2162 $$thing =~ s/%CLIENT6IP/$CLIENT6IP/g;
2163 $$thing =~ s/%RTSPPORT/$RTSPPORT/g;
2164 $$thing =~ s/%RTSP6PORT/$RTSP6PORT/g;
2165 $$thing =~ s/%GOPHERPORT/$GOPHERPORT/g;
2166 $$thing =~ s/%GOPHER6PORT/$GOPHER6PORT/g;
2168 # The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be
2169 # used for time-out tests and that whould work on most hosts as these
2170 # adjust for the startup/check time for this particular host. We needed
2171 # to do this to make the test suite run better on very slow hosts.
2173 my $ftp2 = $ftpchecktime * 2;
2174 my $ftp3 = $ftpchecktime * 3;
2176 $$thing =~ s/%FTPTIME2/$ftp2/g;
2177 $$thing =~ s/%FTPTIME3/$ftp3/g;
2189 #######################################################################
2190 # Provide time stamps for single test skipped events
2192 sub timestampskippedevents {
2193 my $testnum = $_[0];
2195 return if((not defined($testnum)) || ($testnum < 1));
2199 if($timevrfyend{$testnum}) {
2202 elsif($timesrvrlog{$testnum}) {
2203 $timevrfyend{$testnum} = $timesrvrlog{$testnum};
2206 elsif($timetoolend{$testnum}) {
2207 $timevrfyend{$testnum} = $timetoolend{$testnum};
2208 $timesrvrlog{$testnum} = $timetoolend{$testnum};
2210 elsif($timetoolini{$testnum}) {
2211 $timevrfyend{$testnum} = $timetoolini{$testnum};
2212 $timesrvrlog{$testnum} = $timetoolini{$testnum};
2213 $timetoolend{$testnum} = $timetoolini{$testnum};
2215 elsif($timesrvrend{$testnum}) {
2216 $timevrfyend{$testnum} = $timesrvrend{$testnum};
2217 $timesrvrlog{$testnum} = $timesrvrend{$testnum};
2218 $timetoolend{$testnum} = $timesrvrend{$testnum};
2219 $timetoolini{$testnum} = $timesrvrend{$testnum};
2221 elsif($timesrvrini{$testnum}) {
2222 $timevrfyend{$testnum} = $timesrvrini{$testnum};
2223 $timesrvrlog{$testnum} = $timesrvrini{$testnum};
2224 $timetoolend{$testnum} = $timesrvrini{$testnum};
2225 $timetoolini{$testnum} = $timesrvrini{$testnum};
2226 $timesrvrend{$testnum} = $timesrvrini{$testnum};
2228 elsif($timeprepini{$testnum}) {
2229 $timevrfyend{$testnum} = $timeprepini{$testnum};
2230 $timesrvrlog{$testnum} = $timeprepini{$testnum};
2231 $timetoolend{$testnum} = $timeprepini{$testnum};
2232 $timetoolini{$testnum} = $timeprepini{$testnum};
2233 $timesrvrend{$testnum} = $timeprepini{$testnum};
2234 $timesrvrini{$testnum} = $timeprepini{$testnum};
2239 #######################################################################
2240 # Run a single specified test case
2243 my ($testnum, $count, $total)=@_;
2249 my $disablevalgrind;
2251 # copy test number to a global scope var, this allows
2252 # testnum checking when starting test harness servers.
2253 $testnumcheck = $testnum;
2255 # timestamp test preparation start
2256 $timeprepini{$testnum} = Time::HiRes::time() if($timestats);
2258 if($disttests !~ /test$testnum\W/ ) {
2259 logmsg "Warning: test$testnum not present in tests/data/Makefile.am\n";
2262 # load the test case file definition
2263 if(loadtest("${TESTDIR}/test${testnum}")) {
2265 # this is not a test
2266 logmsg "RUN: $testnum doesn't look like a test case\n";
2271 @what = getpart("client", "features");
2278 $feature{$f}=$f; # we require this feature
2285 elsif($f eq "OpenSSL") {
2290 elsif($f eq "GnuTLS") {
2295 elsif($f eq "NSS") {
2300 elsif($f eq "netrc_debug") {
2305 elsif($f eq "large_file") {
2310 elsif($f eq "idn") {
2315 elsif($f eq "ipv6") {
2320 elsif($f eq "libz") {
2325 elsif($f eq "NTLM") {
2330 elsif($f eq "getrlimit") {
2331 if($has_getrlimit) {
2335 elsif($f eq "crypto") {
2340 elsif($f eq "socks") {
2343 # See if this "feature" is in the list of supported protocols
2344 elsif (grep /^$f$/, @protocols) {
2348 $why = "curl lacks $f support";
2353 my @keywords = getpart("info", "keywords");
2356 for $k (@keywords) {
2358 if ($disabled_keywords{$k}) {
2359 $why = "disabled by keyword";
2360 } elsif ($enabled_keywords{$k}) {
2365 if(!$why && !$match && %enabled_keywords) {
2366 $why = "disabled by missing keyword";
2370 # test definition may instruct to (un)set environment vars
2371 # this is done this early, so that the precheck can use environment
2372 # variables and still bail out fine on errors
2374 # restore environment variables that were modified in a previous run
2375 foreach my $var (keys %oldenv) {
2376 if($oldenv{$var} eq 'notset') {
2377 delete $ENV{$var} if($ENV{$var});
2380 $ENV{$var} = $oldenv{$var};
2382 delete $oldenv{$var};
2385 # timestamp required servers verification start
2386 $timesrvrini{$testnum} = Time::HiRes::time() if($timestats);
2389 $why = serverfortest($testnum);
2392 # timestamp required servers verification end
2393 $timesrvrend{$testnum} = Time::HiRes::time() if($timestats);
2395 my @setenv = getpart("client", "setenv");
2397 foreach my $s (@setenv) {
2400 if($s =~ /([^=]*)=(.*)/) {
2401 my ($var, $content) = ($1, $2);
2402 # remember current setting, to restore it once test runs
2403 $oldenv{$var} = ($ENV{$var})?"$ENV{$var}":'notset';
2406 delete $ENV{$var} if($ENV{$var});
2409 if(($var =~ /^LD_PRELOAD/) &&
2410 ($debug_build || ($has_shared ne "yes"))) {
2411 # print "Skipping LD_PRELOAD due to no release shared build\n";
2414 $ENV{$var} = "$content";
2422 # Add a precheck cache. If a precheck command was already invoked
2423 # exactly like this, then use the previous result to speed up
2424 # successive test invokes!
2426 my @precheck = getpart("client", "precheck");
2428 $cmd = $precheck[0];
2432 my @p = split(/ /, $cmd);
2434 # the first word, the command, does not contain a slash so
2435 # we will scan the "improved" PATH to find the command to
2437 my $fullp = checktestcmd($p[0]);
2442 $cmd = join(" ", @p);
2445 my @o = `$cmd 2>/dev/null`;
2450 $why = "precheck command error";
2452 logmsg "prechecked $cmd\n" if($verbose);
2457 if($why && !$listonly) {
2458 # there's a problem, count it as "skipped"
2461 $teststat[$testnum]=$why; # store reason for this test case
2464 printf "test %03d SKIPPED: $why\n", $testnum;
2467 timestampskippedevents($testnum);
2470 logmsg sprintf("test %03d...", $testnum);
2472 # extract the reply data
2473 my @reply = getpart("reply", "data");
2474 my @replycheck = getpart("reply", "datacheck");
2477 # we use this file instead to check the final output against
2479 my %hash = getpartattr("reply", "datacheck");
2480 if($hash{'nonewline'}) {
2481 # Yes, we must cut off the final newline from the final line
2483 chomp($replycheck[$#replycheck]);
2489 # this is the valid protocol blurb curl should generate
2490 my @protocol= fixarray ( getpart("verify", "protocol") );
2492 # redirected stdout/stderr to these files
2493 $STDOUT="$LOGDIR/stdout$testnum";
2494 $STDERR="$LOGDIR/stderr$testnum";
2496 # if this section exists, we verify that the stdout contained this:
2497 my @validstdout = fixarray ( getpart("verify", "stdout") );
2499 # if this section exists, we verify upload
2500 my @upload = getpart("verify", "upload");
2502 # if this section exists, it might be FTP server instructions:
2503 my @ftpservercmd = getpart("reply", "servercmd");
2505 my $CURLOUT="$LOGDIR/curl$testnum.out"; # curl output if not stdout
2508 my @testname= getpart("client", "name");
2511 my $name = $testname[0];
2517 timestampskippedevents($testnum);
2518 return 0; # look successful
2521 my @codepieces = getpart("client", "tool");
2525 $tool = $codepieces[0];
2529 # remove server output logfiles
2534 # write the instructions to file
2535 writearray($FTPDCMD, \@ftpservercmd);
2538 # get the command line options to use
2540 ($cmd, @blaha)= getpart("client", "command");
2543 # make some nice replace operations
2544 $cmd =~ s/\n//g; # no newlines please
2545 # substitute variables in the command line
2552 # create a (possibly-empty) file before starting the test
2553 my @inputfile=getpart("client", "file");
2554 my %fileattr = getpartattr("client", "file");
2555 my $filename=$fileattr{'name'};
2556 if(@inputfile || $filename) {
2558 logmsg "ERROR: section client=>file has no name attribute\n";
2559 timestampskippedevents($testnum);
2562 my $fileContent = join('', @inputfile);
2563 subVariables \$fileContent;
2564 # logmsg "DEBUG: writing file " . $filename . "\n";
2565 open(OUTFILE, ">$filename");
2566 binmode OUTFILE; # for crapage systems, use binary
2567 print OUTFILE $fileContent;
2571 my %cmdhash = getpartattr("client", "command");
2575 if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-output/)) {
2576 #We may slap on --output!
2577 if (!@validstdout) {
2578 $out=" --output $CURLOUT ";
2582 my $serverlogslocktimeout = $defserverlogslocktimeout;
2583 if($cmdhash{'timeout'}) {
2584 # test is allowed to override default server logs lock timeout
2585 if($cmdhash{'timeout'} =~ /(\d+)/) {
2586 $serverlogslocktimeout = $1 if($1 >= 0);
2590 my $postcommanddelay = $defpostcommanddelay;
2591 if($cmdhash{'delay'}) {
2592 # test is allowed to specify a delay after command is executed
2593 if($cmdhash{'delay'} =~ /(\d+)/) {
2594 $postcommanddelay = $1 if($1 > 0);
2600 my $cmdtype = $cmdhash{'type'} || "default";
2601 if($cmdtype eq "perl") {
2602 # run the command line prepended with "perl"
2609 # run curl, add --verbose for debug information output
2610 $cmdargs ="$out --include --verbose --trace-time $cmd";
2613 $cmdargs = " $cmd"; # $cmd is the command line for the test file
2614 $CURLOUT = $STDOUT; # sends received data to stdout
2616 $CMDLINE="$LIBDIR/$tool";
2618 print "The tool set in the test case for this: '$tool' does not exist\n";
2619 timestampskippedevents($testnum);
2625 my @stdintest = getpart("client", "stdin");
2628 my $stdinfile="$LOGDIR/stdin-for-$testnum";
2629 writearray($stdinfile, \@stdintest);
2631 $cmdargs .= " <$stdinfile";
2639 if($valgrind && !$disablevalgrind) {
2640 my @valgrindoption = getpart("verify", "valgrind");
2641 if((!@valgrindoption) || ($valgrindoption[0] !~ /disable/)) {
2643 my $valgrindcmd = "$valgrind ";
2644 $valgrindcmd .= "$valgrind_tool " if($valgrind_tool);
2645 $valgrindcmd .= "--leak-check=yes ";
2646 $valgrindcmd .= "--num-callers=16 ";
2647 $valgrindcmd .= "${valgrind_logfile}=$LOGDIR/valgrind$testnum";
2648 $CMDLINE = "$valgrindcmd $CMDLINE";
2652 $CMDLINE .= "$cmdargs >$STDOUT 2>$STDERR";
2655 logmsg "$CMDLINE\n";
2658 print CMDLOG "$CMDLINE\n";
2665 # Apr 2007: precommand isn't being used and could be removed
2666 my @precommand= getpart("client", "precommand");
2667 if($precommand[0]) {
2668 # this is pure perl to eval!
2669 my $code = join("", @precommand);
2672 logmsg "perl: $code\n";
2673 logmsg "precommand: $@";
2674 stopservers($verbose);
2675 timestampskippedevents($testnum);
2681 my $gdbinit = "$TESTDIR/gdbinit$testnum";
2682 open(GDBCMD, ">$LOGDIR/gdbcmd");
2683 print GDBCMD "set args $cmdargs\n";
2684 print GDBCMD "show args\n";
2685 print GDBCMD "source $gdbinit\n" if -e $gdbinit;
2689 # timestamp starting of test command
2690 $timetoolini{$testnum} = Time::HiRes::time() if($timestats);
2692 # run the command line we built
2694 $cmdres = torture($CMDLINE,
2695 "libtool --mode=execute gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
2698 runclient("libtool --mode=execute gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
2699 $cmdres=0; # makes it always continue after a debugged run
2702 $cmdres = runclient("$CMDLINE");
2703 my $signal_num = $cmdres & 127;
2704 $dumped_core = $cmdres & 128;
2706 if(!$anyway && ($signal_num || $dumped_core)) {
2711 $cmdres = (2000 + $signal_num) if($signal_num && !$cmdres);
2715 # timestamp finishing of test command
2716 $timetoolend{$testnum} = Time::HiRes::time() if($timestats);
2720 # there's core file present now!
2726 logmsg "core dumped\n";
2728 logmsg "running gdb for post-mortem analysis:\n";
2729 open(GDBCMD, ">$LOGDIR/gdbcmd2");
2730 print GDBCMD "bt\n";
2732 runclient("libtool --mode=execute gdb --directory libtest -x $LOGDIR/gdbcmd2 -batch $DBGCURL core ");
2733 # unlink("$LOGDIR/gdbcmd2");
2737 # If a server logs advisor read lock file exists, it is an indication
2738 # that the server has not yet finished writing out all its log files,
2739 # including server request log files used for protocol verification.
2740 # So, if the lock file exists the script waits here a certain amount
2741 # of time until the server removes it, or the given time expires.
2743 if($serverlogslocktimeout) {
2744 my $lockretry = $serverlogslocktimeout * 20;
2745 while((-f $SERVERLOGS_LOCK) && $lockretry--) {
2746 select(undef, undef, undef, 0.05);
2748 if(($lockretry < 0) &&
2749 ($serverlogslocktimeout >= $defserverlogslocktimeout)) {
2750 logmsg "Warning: server logs lock timeout ",
2751 "($serverlogslocktimeout seconds) expired\n";
2755 # Test harness ssh server does not have this synchronization mechanism,
2756 # this implies that some ssh server based tests might need a small delay
2757 # once that the client command has run to avoid false test failures.
2759 sleep($postcommanddelay) if($postcommanddelay);
2761 # timestamp removal of server logs advisor read lock
2762 $timesrvrlog{$testnum} = Time::HiRes::time() if($timestats);
2764 # test definition might instruct to stop some servers
2765 # stop also all servers relative to the given one
2767 my @killtestservers = getpart("client", "killserver");
2768 if(@killtestservers) {
2770 # All servers relative to the given one must be stopped also
2773 foreach my $server (@killtestservers) {
2775 if($server =~ /^(ftp|http|imap|pop3|smtp)s(.*)$/) {
2776 # given an ssl server, also kill non-ssl underlying one
2777 push @killservers, "${1}${2}";
2779 elsif($server =~ /^(ftp|http|imap|pop3|smtp)(.*)$/) {
2780 # given a non-ssl server, also kill ssl piggybacking one
2781 push @killservers, "${1}s${2}";
2783 elsif($server =~ /^(socks)(.*)$/) {
2784 # given an socks server, also kill ssh underlying one
2785 push @killservers, "ssh${2}";
2787 elsif($server =~ /^(ssh)(.*)$/) {
2788 # given an ssh server, also kill socks piggybacking one
2789 push @killservers, "socks${2}";
2791 push @killservers, $server;
2794 # kill sockfilter processes for pingpong relative servers
2796 foreach my $server (@killservers) {
2797 if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
2799 my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
2800 my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
2801 killsockfilters($proto, $ipvnum, $idnum, $verbose);
2805 # kill server relative pids clearing them in %run hash
2808 foreach my $server (@killservers) {
2810 $pidlist .= "$run{$server} ";
2813 $runcert{$server} = 0 if($runcert{$server});
2815 killpid($verbose, $pidlist);
2817 # cleanup server pid files
2819 foreach my $server (@killservers) {
2820 my $pidfile = $serverpidfile{$server};
2821 my $pid = processexists($pidfile);
2823 logmsg "Warning: $server server unexpectedly alive\n";
2824 killpid($verbose, $pid);
2826 unlink($pidfile) if(-f $pidfile);
2830 # remove the test server commands file after each test
2833 # run the postcheck command
2834 my @postcheck= getpart("client", "postcheck");
2836 $cmd = $postcheck[0];
2840 logmsg "postcheck $cmd\n" if($verbose);
2841 my $rc = runclient("$cmd");
2842 # Must run the postcheck command in torture mode in order
2843 # to clean up, but the result can't be relied upon.
2844 if($rc != 0 && !$torture) {
2845 logmsg " postcheck FAILED\n";
2846 # timestamp test result verification end
2847 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2853 # restore environment variables that were modified
2855 foreach my $var (keys %oldenv) {
2856 if($oldenv{$var} eq 'notset') {
2857 delete $ENV{$var} if($ENV{$var});
2860 $ENV{$var} = "$oldenv{$var}";
2865 # Skip all the verification on torture tests
2867 if(!$cmdres && !$keepoutfiles) {
2870 # timestamp test result verification end
2871 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2875 my @err = getpart("verify", "errorcode");
2876 my $errorcode = $err[0] || "0";
2880 # verify redirected stdout
2881 my @actual = loadarray($STDOUT);
2883 # variable-replace in the stdout we have from the test case file
2884 @validstdout = fixarray(@validstdout);
2886 # get all attributes
2887 my %hash = getpartattr("verify", "stdout");
2889 # get the mode attribute
2890 my $filemode=$hash{'mode'};
2891 if($filemode && ($filemode eq "text") && $has_textaware) {
2892 # text mode when running on windows: fix line endings
2893 map s/\r\n/\n/g, @actual;
2896 if($hash{'nonewline'}) {
2897 # Yes, we must cut off the final newline from the final line
2898 # of the protocol data
2899 chomp($validstdout[$#validstdout]);
2902 $res = compare("stdout", \@actual, \@validstdout);
2904 # timestamp test result verification end
2905 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2911 $ok .= "-"; # stdout not checked
2914 my %replyattr = getpartattr("reply", "data");
2915 if(!$replyattr{'nocheck'} && (@reply || $replyattr{'sendzero'})) {
2916 # verify the received data
2917 my @out = loadarray($CURLOUT);
2918 my %hash = getpartattr("reply", "data");
2919 # get the mode attribute
2920 my $filemode=$hash{'mode'};
2921 if($filemode && ($filemode eq "text") && $has_textaware) {
2922 # text mode when running on windows: fix line endings
2923 map s/\r\n/\n/g, @out;
2926 $res = compare("data", \@out, \@reply);
2928 # timestamp test result verification end
2929 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2935 $ok .= "-"; # data not checked
2939 # verify uploaded data
2940 my @out = loadarray("$LOGDIR/upload.$testnum");
2941 $res = compare("upload", \@out, \@upload);
2943 # timestamp test result verification end
2944 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2950 $ok .= "-"; # upload not checked
2954 # Verify the sent request
2955 my @out = loadarray($SERVERIN);
2957 # what to cut off from the live protocol sent by curl
2958 my @strip = getpart("verify", "strip");
2960 my @protstrip=@protocol;
2962 # check if there's any attributes on the verify/protocol section
2963 my %hash = getpartattr("verify", "protocol");
2965 if($hash{'nonewline'}) {
2966 # Yes, we must cut off the final newline from the final line
2967 # of the protocol data
2968 chomp($protstrip[$#protstrip]);
2972 # strip off all lines that match the patterns from both arrays
2974 @out = striparray( $_, \@out);
2975 @protstrip= striparray( $_, \@protstrip);
2978 # what parts to cut off from the protocol
2979 my @strippart = getpart("verify", "strippart");
2981 for $strip (@strippart) {
2988 $res = compare("protocol", \@out, \@protstrip);
2990 # timestamp test result verification end
2991 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2999 $ok .= "-"; # protocol not checked
3002 my @outfile=getpart("verify", "file");
3004 # we're supposed to verify a dynamically generated file!
3005 my %hash = getpartattr("verify", "file");
3007 my $filename=$hash{'name'};
3009 logmsg "ERROR: section verify=>file has no name attribute\n";
3010 stopservers($verbose);
3011 # timestamp test result verification end
3012 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3015 my @generated=loadarray($filename);
3017 # what parts to cut off from the file
3018 my @stripfile = getpart("verify", "stripfile");
3020 my $filemode=$hash{'mode'};
3021 if($filemode && ($filemode eq "text") && $has_textaware) {
3022 # text mode when running on windows means adding an extra
3024 push @stripfile, "s/\r\n/\n/";
3028 for $strip (@stripfile) {
3035 @outfile = fixarray(@outfile);
3037 $res = compare("output", \@generated, \@outfile);
3039 # timestamp test result verification end
3040 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3047 $ok .= "-"; # output not checked
3050 # accept multiple comma-separated error codes
3051 my @splerr = split(/ *, */, $errorcode);
3053 foreach my $e (@splerr) {
3066 printf("\n%s returned $cmdres, %d was expected\n",
3067 (!$tool)?"curl":$tool, $errorcode);
3069 logmsg " exit FAILED\n";
3070 # timestamp test result verification end
3071 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3077 logmsg "\n** ALERT! memory debugging with no output file?\n"
3078 if(!$cmdtype eq "perl");
3081 my @memdata=`$memanalyze $memdump`;
3085 # well it could be other memory problems as well, but
3086 # we call it leak for short here
3091 logmsg "\n** MEMORY FAILURE\n";
3093 # timestamp test result verification end
3094 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3103 $ok .= "-"; # memory not checked
3108 unless(opendir(DIR, "$LOGDIR")) {
3109 logmsg "ERROR: unable to read $LOGDIR\n";
3110 # timestamp test result verification end
3111 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3114 my @files = readdir(DIR);
3117 foreach my $file (@files) {
3118 if($file =~ /^valgrind$testnum(\..*|)$/) {
3124 logmsg "ERROR: valgrind log file missing for test $testnum\n";
3125 # timestamp test result verification end
3126 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3129 my @e = valgrindparse($srcdir, $feature{'SSL'}, "$LOGDIR/$vgfile");
3131 logmsg " valgrind ERROR ";
3133 # timestamp test result verification end
3134 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3140 if(!$short && !$disablevalgrind) {
3141 logmsg " valgrind SKIPPED\n";
3143 $ok .= "-"; # skipped
3147 $ok .= "-"; # valgrind not checked
3150 logmsg "$ok " if(!$short);
3152 my $sofar= time()-$start;
3153 my $esttotal = $sofar/$count * $total;
3154 my $estleft = $esttotal - $sofar;
3155 my $left=sprintf("remaining: %02d:%02d",
3158 printf "OK (%-3d out of %-3d, %s)\n", $count, $total, $left;
3160 # the test succeeded, remove all log files
3161 if(!$keepoutfiles) {
3165 # timestamp test result verification end
3166 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3171 #######################################################################
3172 # Stop all running test servers
3174 my $verbose = $_[0];
3176 # kill sockfilter processes for all pingpong servers
3178 killallsockfilters($verbose);
3180 # kill all server pids from %run hash clearing them
3183 foreach my $server (keys %run) {
3187 my $pids = $run{$server};
3188 foreach my $pid (split(' ', $pids)) {
3190 logmsg sprintf("* kill pid for %s => %d\n",
3196 $pidlist .= "$run{$server} ";
3199 $runcert{$server} = 0 if($runcert{$server});
3201 killpid($verbose, $pidlist);
3203 # cleanup all server pid files
3205 foreach my $server (keys %serverpidfile) {
3206 my $pidfile = $serverpidfile{$server};
3207 my $pid = processexists($pidfile);
3209 logmsg "Warning: $server server unexpectedly alive\n";
3210 killpid($verbose, $pid);
3212 unlink($pidfile) if(-f $pidfile);
3216 #######################################################################
3217 # startservers() starts all the named servers
3219 # Returns: string with error reason or blank for success
3225 my (@whatlist) = split(/\s+/,$_);
3226 my $what = lc($whatlist[0]);
3227 $what =~ s/[^a-z0-9-]//g;
3230 if($what =~ /^(ftp|http|imap|pop3|smtp)s(.*)$/) {
3231 $certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem';
3234 if(($what eq "pop3") ||
3236 ($what eq "imap") ||
3237 ($what eq "smtp")) {
3239 ($pid, $pid2) = runpingpongserver($what, "", $verbose);
3241 return "failed starting ". uc($what) ." server";
3243 printf ("* pid $what => %d %d\n", $pid, $pid2) if($verbose);
3244 $run{$what}="$pid $pid2";
3247 elsif($what eq "ftp2") {
3249 ($pid, $pid2) = runpingpongserver("ftp", "2", $verbose);
3251 return "failed starting FTP2 server";
3253 printf ("* pid ftp2 => %d %d\n", $pid, $pid2) if($verbose);
3254 $run{'ftp2'}="$pid $pid2";
3257 elsif($what eq "ftp-ipv6") {
3258 if(!$run{'ftp-ipv6'}) {
3259 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose, "ipv6");
3261 return "failed starting FTP-IPv6 server";
3263 logmsg sprintf("* pid ftp-ipv6 => %d %d\n", $pid,
3264 $pid2) if($verbose);
3265 $run{'ftp-ipv6'}="$pid $pid2";
3268 elsif($what eq "gopher") {
3269 if(!$run{'gopher'}) {
3270 ($pid, $pid2) = runhttpserver("gopher", $verbose, 0,
3273 return "failed starting GOPHER server";
3275 printf ("* pid gopher => %d %d\n", $pid, $pid2) if($verbose);
3276 $run{'gopher'}="$pid $pid2";
3279 elsif($what eq "gopher-ipv6") {
3280 if(!$run{'gopher-ipv6'}) {
3281 ($pid, $pid2) = runhttpserver("gopher", $verbose, "ipv6",
3284 return "failed starting GOPHER-IPv6 server";
3286 logmsg sprintf("* pid gopher-ipv6 => %d %d\n", $pid,
3287 $pid2) if($verbose);
3288 $run{'gopher-ipv6'}="$pid $pid2";
3291 elsif($what eq "http") {
3293 ($pid, $pid2) = runhttpserver("http", $verbose, 0,
3296 return "failed starting HTTP server";
3298 printf ("* pid http => %d %d\n", $pid, $pid2) if($verbose);
3299 $run{'http'}="$pid $pid2";
3302 elsif($what eq "http-ipv6") {
3303 if(!$run{'http-ipv6'}) {
3304 ($pid, $pid2) = runhttpserver("http", $verbose, "IPv6",
3307 return "failed starting HTTP-IPv6 server";
3309 logmsg sprintf("* pid http-ipv6 => %d %d\n", $pid, $pid2)
3311 $run{'http-ipv6'}="$pid $pid2";
3314 elsif($what eq "rtsp") {
3316 ($pid, $pid2) = runrtspserver($verbose);
3318 return "failed starting RTSP server";
3320 printf ("* pid rtsp => %d %d\n", $pid, $pid2) if($verbose);
3321 $run{'rtsp'}="$pid $pid2";
3324 elsif($what eq "rtsp-ipv6") {
3325 if(!$run{'rtsp-ipv6'}) {
3326 ($pid, $pid2) = runrtspserver($verbose, "IPv6");
3328 return "failed starting RTSP-IPv6 server";
3330 logmsg sprintf("* pid rtsp-ipv6 => %d %d\n", $pid, $pid2)
3332 $run{'rtsp-ipv6'}="$pid $pid2";
3336 elsif($what eq "ftps") {
3338 # we can't run ftps tests without stunnel
3339 return "no stunnel";
3342 # we can't run ftps tests if libcurl is SSL-less
3343 return "curl lacks SSL support";
3345 if($runcert{'ftps'} && ($runcert{'ftps'} ne $certfile)) {
3346 # stop server when running and using a different cert
3350 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose);
3352 return "failed starting FTP server";
3354 printf ("* pid ftp => %d %d\n", $pid, $pid2) if($verbose);
3355 $run{'ftp'}="$pid $pid2";
3358 ($pid, $pid2) = runftpsserver($verbose, "", $certfile);
3360 return "failed starting FTPS server (stunnel)";
3362 logmsg sprintf("* pid ftps => %d %d\n", $pid, $pid2)
3364 $run{'ftps'}="$pid $pid2";
3367 elsif($what eq "file") {
3368 # we support it but have no server!
3370 elsif($what eq "https") {
3372 # we can't run ftps tests without stunnel
3373 return "no stunnel";
3376 # we can't run ftps tests if libcurl is SSL-less
3377 return "curl lacks SSL support";
3379 if($runcert{'https'} && ($runcert{'https'} ne $certfile)) {
3380 # stop server when running and using a different cert
3381 stopserver('https');
3384 ($pid, $pid2) = runhttpserver("http", $verbose, 0,
3387 return "failed starting HTTP server";
3389 printf ("* pid http => %d %d\n", $pid, $pid2) if($verbose);
3390 $run{'http'}="$pid $pid2";
3392 if(!$run{'https'}) {
3393 ($pid, $pid2) = runhttpsserver($verbose, "", $certfile);
3395 return "failed starting HTTPS server (stunnel)";
3397 logmsg sprintf("* pid https => %d %d\n", $pid, $pid2)
3399 $run{'https'}="$pid $pid2";
3402 elsif($what eq "tftp") {
3404 ($pid, $pid2) = runtftpserver("", $verbose);
3406 return "failed starting TFTP server";
3408 printf ("* pid tftp => %d %d\n", $pid, $pid2) if($verbose);
3409 $run{'tftp'}="$pid $pid2";
3412 elsif($what eq "tftp-ipv6") {
3413 if(!$run{'tftp-ipv6'}) {
3414 ($pid, $pid2) = runtftpserver("", $verbose, "IPv6");
3416 return "failed starting TFTP-IPv6 server";
3418 printf("* pid tftp-ipv6 => %d %d\n", $pid, $pid2) if($verbose);
3419 $run{'tftp-ipv6'}="$pid $pid2";
3422 elsif($what eq "sftp" || $what eq "scp" || $what eq "socks4" || $what eq "socks5" ) {
3424 ($pid, $pid2) = runsshserver("", $verbose);
3426 return "failed starting SSH server";
3428 printf ("* pid ssh => %d %d\n", $pid, $pid2) if($verbose);
3429 $run{'ssh'}="$pid $pid2";
3431 if($what eq "socks4" || $what eq "socks5") {
3432 if(!$run{'socks'}) {
3433 ($pid, $pid2) = runsocksserver("", $verbose);
3435 return "failed starting socks server";
3437 printf ("* pid socks => %d %d\n", $pid, $pid2) if($verbose);
3438 $run{'socks'}="$pid $pid2";
3441 if($what eq "socks5") {
3443 # Not an OpenSSH or SunSSH ssh daemon
3444 logmsg "Not OpenSSH or SunSSH; socks5 tests need at least OpenSSH 3.7\n";
3445 return "failed starting socks5 server";
3447 elsif(($sshdid =~ /OpenSSH/) && ($sshdvernum < 370)) {
3448 # Need OpenSSH 3.7 for socks5 - http://www.openssh.com/txt/release-3.7
3449 logmsg "$sshdverstr insufficient; socks5 tests need at least OpenSSH 3.7\n";
3450 return "failed starting socks5 server";
3452 elsif(($sshdid =~ /SunSSH/) && ($sshdvernum < 100)) {
3453 # Need SunSSH 1.0 for socks5
3454 logmsg "$sshdverstr insufficient; socks5 tests need at least SunSSH 1.0\n";
3455 return "failed starting socks5 server";
3459 elsif($what eq "none") {
3460 logmsg "* starts no server\n" if ($verbose);
3463 warn "we don't support a server for $what";
3464 return "no server for $what";
3470 ##############################################################################
3471 # This function makes sure the right set of server is running for the
3472 # specified test case. This is a useful design when we run single tests as not
3473 # all servers need to run then!
3475 # Returns: a string, blank if everything is fine or a reason why it failed
3481 my @what = getpart("client", "server");
3484 warn "Test case $testnum has no server(s) specified";
3485 return "no server specified";
3491 $proto =~ s/\s.*//g; # take first word
3492 if (! grep /^$proto$/, @protocols) {
3493 if (substr($proto,0,5) ne "socks") {
3494 return "curl lacks $proto support";
3499 return &startservers(@what);
3502 #######################################################################
3503 # runtimestats displays test-suite run time statistics
3506 my $lasttest = $_[0];
3508 return if(not $timestats);
3510 logmsg "\nTest suite total running time breakdown per task...\n\n";
3518 my $timesrvrtot = 0.0;
3519 my $timepreptot = 0.0;
3520 my $timetooltot = 0.0;
3521 my $timelocktot = 0.0;
3522 my $timevrfytot = 0.0;
3523 my $timetesttot = 0.0;
3526 for my $testnum (1 .. $lasttest) {
3527 if($timesrvrini{$testnum}) {
3528 $timesrvrtot += $timesrvrend{$testnum} - $timesrvrini{$testnum};
3530 (($timetoolini{$testnum} - $timeprepini{$testnum}) -
3531 ($timesrvrend{$testnum} - $timesrvrini{$testnum}));
3532 $timetooltot += $timetoolend{$testnum} - $timetoolini{$testnum};
3533 $timelocktot += $timesrvrlog{$testnum} - $timetoolend{$testnum};
3534 $timevrfytot += $timevrfyend{$testnum} - $timesrvrlog{$testnum};
3535 $timetesttot += $timevrfyend{$testnum} - $timeprepini{$testnum};
3536 push @timesrvr, sprintf("%06.3f %04d",
3537 $timesrvrend{$testnum} - $timesrvrini{$testnum}, $testnum);
3538 push @timeprep, sprintf("%06.3f %04d",
3539 ($timetoolini{$testnum} - $timeprepini{$testnum}) -
3540 ($timesrvrend{$testnum} - $timesrvrini{$testnum}), $testnum);
3541 push @timetool, sprintf("%06.3f %04d",
3542 $timetoolend{$testnum} - $timetoolini{$testnum}, $testnum);
3543 push @timelock, sprintf("%06.3f %04d",
3544 $timesrvrlog{$testnum} - $timetoolend{$testnum}, $testnum);
3545 push @timevrfy, sprintf("%06.3f %04d",
3546 $timevrfyend{$testnum} - $timesrvrlog{$testnum}, $testnum);
3547 push @timetest, sprintf("%06.3f %04d",
3548 $timevrfyend{$testnum} - $timeprepini{$testnum}, $testnum);
3553 no warnings 'numeric';
3554 @timesrvr = sort { $b <=> $a } @timesrvr;
3555 @timeprep = sort { $b <=> $a } @timeprep;
3556 @timetool = sort { $b <=> $a } @timetool;
3557 @timelock = sort { $b <=> $a } @timelock;
3558 @timevrfy = sort { $b <=> $a } @timevrfy;
3559 @timetest = sort { $b <=> $a } @timetest;
3562 logmsg "Spent ". sprintf("%08.3f ", $timesrvrtot) .
3563 "seconds starting and verifying test harness servers.\n";
3564 logmsg "Spent ". sprintf("%08.3f ", $timepreptot) .
3565 "seconds reading definitions and doing test preparations.\n";
3566 logmsg "Spent ". sprintf("%08.3f ", $timetooltot) .
3567 "seconds actually running test tools.\n";
3568 logmsg "Spent ". sprintf("%08.3f ", $timelocktot) .
3569 "seconds awaiting server logs lock removal.\n";
3570 logmsg "Spent ". sprintf("%08.3f ", $timevrfytot) .
3571 "seconds verifying test results.\n";
3572 logmsg "Spent ". sprintf("%08.3f ", $timetesttot) .
3573 "seconds doing all of the above.\n";
3576 logmsg "\nTest server starting and verification time per test ".
3577 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3578 logmsg "-time- test\n";
3579 logmsg "------ ----\n";
3580 foreach my $txt (@timesrvr) {
3581 last if((not $fullstats) && (not $counter--));
3586 logmsg "\nTest definition reading and preparation time per test ".
3587 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3588 logmsg "-time- test\n";
3589 logmsg "------ ----\n";
3590 foreach my $txt (@timeprep) {
3591 last if((not $fullstats) && (not $counter--));
3596 logmsg "\nTest tool execution time per test ".
3597 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3598 logmsg "-time- test\n";
3599 logmsg "------ ----\n";
3600 foreach my $txt (@timetool) {
3601 last if((not $fullstats) && (not $counter--));
3606 logmsg "\nTest server logs lock removal time per test ".
3607 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3608 logmsg "-time- test\n";
3609 logmsg "------ ----\n";
3610 foreach my $txt (@timelock) {
3611 last if((not $fullstats) && (not $counter--));
3616 logmsg "\nTest results verification time per test ".
3617 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3618 logmsg "-time- test\n";
3619 logmsg "------ ----\n";
3620 foreach my $txt (@timevrfy) {
3621 last if((not $fullstats) && (not $counter--));
3626 logmsg "\nTotal time per test ".
3627 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3628 logmsg "-time- test\n";
3629 logmsg "------ ----\n";
3630 foreach my $txt (@timetest) {
3631 last if((not $fullstats) && (not $counter--));
3638 #######################################################################
3639 # Check options to this test program
3647 if ($ARGV[0] eq "-v") {
3651 elsif($ARGV[0] =~ /^-b(.*)/) {
3653 if($portno =~ s/(\d+)$//) {
3657 elsif ($ARGV[0] eq "-c") {
3658 # use this path to curl instead of default
3659 $DBGCURL=$CURL=$ARGV[1];
3662 elsif ($ARGV[0] eq "-d") {
3663 # have the servers display protocol output
3666 elsif ($ARGV[0] eq "-f") {
3667 # run fork-servers, which makes the server fork for all new
3668 # connections This is NOT what you wanna do without knowing exactly
3672 elsif ($ARGV[0] eq "-g") {
3673 # run this test with gdb
3676 elsif($ARGV[0] eq "-s") {
3680 elsif($ARGV[0] eq "-n") {
3684 elsif($ARGV[0] =~ /^-t(.*)/) {
3689 if($xtra =~ s/(\d+)$//) {
3692 # we undef valgrind to make this fly in comparison
3695 elsif($ARGV[0] eq "-a") {
3696 # continue anyway, even if a test fail
3699 elsif($ARGV[0] eq "-p") {
3702 elsif($ARGV[0] eq "-l") {
3703 # lists the test case names only
3706 elsif($ARGV[0] eq "-k") {
3707 # keep stdout and stderr files after tests
3710 elsif($ARGV[0] eq "-r") {
3711 # run time statistics needs Time::HiRes
3712 if($Time::HiRes::VERSION) {
3713 keys(%timeprepini) = 1000;
3714 keys(%timesrvrini) = 1000;
3715 keys(%timesrvrend) = 1000;
3716 keys(%timetoolini) = 1000;
3717 keys(%timetoolend) = 1000;
3718 keys(%timesrvrlog) = 1000;
3719 keys(%timevrfyend) = 1000;
3724 elsif($ARGV[0] eq "-rf") {
3725 # run time statistics needs Time::HiRes
3726 if($Time::HiRes::VERSION) {
3727 keys(%timeprepini) = 1000;
3728 keys(%timesrvrini) = 1000;
3729 keys(%timesrvrend) = 1000;
3730 keys(%timetoolini) = 1000;
3731 keys(%timetoolend) = 1000;
3732 keys(%timesrvrlog) = 1000;
3733 keys(%timevrfyend) = 1000;
3738 elsif(($ARGV[0] eq "-h") || ($ARGV[0] eq "--help")) {
3741 Usage: runtests.pl [options] [test selection(s)]
3742 -a continue even if a test fails
3743 -bN use base port number N for test servers (default $base)
3744 -c path use this curl executable
3745 -d display server debug info
3746 -g run the test case with gdb
3748 -k keep stdout and stderr files present after tests
3749 -l list all test case names/descriptions
3751 -p print log file contents when a test fails
3752 -r run time statistics
3753 -rf full run time statistics
3755 -t[N] torture (simulate memory alloc failures); N means fail Nth alloc
3757 [num] like "5 6 9" or " 5 to 22 " to run those tests only
3758 [!num] like "!5 !6 !9" to disable those tests
3759 [keyword] like "IPv6" to select only tests containing the key word
3760 [!keyword] like "!cookies" to disable any tests containing the key word
3765 elsif($ARGV[0] =~ /^(\d+)/) {
3768 for($fromnum .. $number) {
3777 elsif($ARGV[0] =~ /^to$/i) {
3778 $fromnum = $number+1;
3780 elsif($ARGV[0] =~ /^!(\d+)/) {
3784 elsif($ARGV[0] =~ /^!(.+)/) {
3785 $disabled_keywords{$1}=$1;
3787 elsif($ARGV[0] =~ /^([-[{a-zA-Z].*)/) {
3788 $enabled_keywords{$1}=$1;
3791 print "Unknown option: $ARGV[0]\n";
3797 if(@testthis && ($testthis[0] ne "")) {
3798 $TESTCASES=join(" ", @testthis);
3802 # we have found valgrind on the host, use it
3804 # verify that we can invoke it fine
3805 my $code = runclient("valgrind >/dev/null 2>&1");
3807 if(($code>>8) != 1) {
3808 #logmsg "Valgrind failure, disable it\n";
3812 # since valgrind 2.1.x, '--tool' option is mandatory
3813 # use it, if it is supported by the version installed on the system
3814 runclient("valgrind --help 2>&1 | grep -- --tool > /dev/null 2>&1");
3816 $valgrind_tool="--tool=memcheck";
3821 # A shell script. This is typically when built with libtool,
3822 $valgrind="../libtool --mode=execute $valgrind";
3826 # valgrind 3 renamed the --logfile option to --log-file!!!
3827 my $ver=join(' ', runclientoutput("valgrind --version"));
3828 # cut off all but digits and dots
3829 $ver =~ s/[^0-9.]//g;
3831 if($ver =~ /^(\d+)/) {
3834 $valgrind_logfile="--log-file";
3841 # open the executable curl and read the first 4 bytes of it
3842 open(CHECK, "<$CURL");
3844 sysread CHECK, $c, 4;
3847 # A shell script. This is typically when built with libtool,
3849 $gdb = "libtool --mode=execute gdb";
3853 $HTTPPORT = $base++; # HTTP server port
3854 $HTTPSPORT = $base++; # HTTPS server port
3855 $FTPPORT = $base++; # FTP server port
3856 $FTPSPORT = $base++; # FTPS server port
3857 $HTTP6PORT = $base++; # HTTP IPv6 server port (different IP protocol
3858 # but we follow the same port scheme anyway)
3859 $FTP2PORT = $base++; # FTP server 2 port
3860 $FTP6PORT = $base++; # FTP IPv6 port
3861 $TFTPPORT = $base++; # TFTP (UDP) port
3862 $TFTP6PORT = $base++; # TFTP IPv6 (UDP) port
3863 $SSHPORT = $base++; # SSH (SCP/SFTP) port
3864 $SOCKSPORT = $base++; # SOCKS port
3865 $POP3PORT = $base++;
3866 $POP36PORT = $base++;
3867 $IMAPPORT = $base++;
3868 $IMAP6PORT = $base++;
3869 $SMTPPORT = $base++;
3870 $SMTP6PORT = $base++;
3871 $RTSPPORT = $base++;
3872 $RTSP6PORT = $base++;
3873 $GOPHERPORT =$base++;
3874 $GOPHER6PORT=$base++;
3876 #######################################################################
3877 # clear and create logging directory:
3881 mkdir($LOGDIR, 0777);
3883 #######################################################################
3884 # initialize some variables
3888 init_serverpidfile_hash();
3890 #######################################################################
3891 # Output curl version and host info being tested
3898 #######################################################################
3899 # If 'all' tests are requested, find out all test numbers
3902 if ( $TESTCASES eq "all") {
3903 # Get all commands and find out their test numbers
3904 opendir(DIR, $TESTDIR) || die "can't opendir $TESTDIR: $!";
3905 my @cmds = grep { /^test([0-9]+)$/ && -f "$TESTDIR/$_" } readdir(DIR);
3908 open(D, "<$TESTDIR/DISABLED");
3915 $disabled{$1}=$1; # disable this test number
3920 $TESTCASES=""; # start with no test cases
3922 # cut off everything but the digits
3924 $_ =~ s/[a-z\/\.]*//g;
3926 # sort the numbers from low to high
3927 foreach my $n (sort { $a <=> $b } @cmds) {
3929 # skip disabled test cases
3930 my $why = "configured as DISABLED";
3933 $teststat[$n]=$why; # store reason for this test case
3936 $TESTCASES .= " $n";
3940 #######################################################################
3941 # Start the command line log
3943 open(CMDLOG, ">$CURLLOG") ||
3944 logmsg "can't log command lines to $CURLLOG\n";
3946 #######################################################################
3948 # Display the contents of the given file. Line endings are canonicalized
3949 # and excessively long files are elided
3950 sub displaylogcontent {
3952 if(open(SINGLE, "<$file")) {
3956 while(my $string = <SINGLE>) {
3957 $string =~ s/\r\n/\n/g;
3958 $string =~ s/[\r\f\032]/\n/g;
3959 $string .= "\n" unless ($string =~ /\n$/);
3961 for my $line (split("\n", $string)) {
3962 $line =~ s/\s*\!$//;
3964 push @tail, " $line\n";
3969 $truncate = $linecount > 1000;
3975 my $tailtotal = scalar @tail;
3976 if($tailtotal > $tailshow) {
3977 $tailskip = $tailtotal - $tailshow;
3978 logmsg "=== File too long: $tailskip lines omitted here\n";
3980 for($tailskip .. $tailtotal-1) {
3990 opendir(DIR, "$LOGDIR") ||
3991 die "can't open dir: $!";
3992 my @logs = readdir(DIR);
3995 logmsg "== Contents of files in the $LOGDIR/ dir after test $testnum\n";
3996 foreach my $log (sort @logs) {
3997 if($log =~ /\.(\.|)$/) {
3998 next; # skip "." and ".."
4000 if($log =~ /^\.nfs/) {
4003 if(($log eq "memdump") || ($log eq "core")) {
4004 next; # skip "memdump" and "core"
4006 if((-d "$LOGDIR/$log") || (! -s "$LOGDIR/$log")) {
4007 next; # skip directory and empty files
4009 if(($log =~ /^stdout\d+/) && ($log !~ /^stdout$testnum/)) {
4010 next; # skip stdoutNnn of other tests
4012 if(($log =~ /^stderr\d+/) && ($log !~ /^stderr$testnum/)) {
4013 next; # skip stderrNnn of other tests
4015 if(($log =~ /^upload\d+/) && ($log !~ /^upload$testnum/)) {
4016 next; # skip uploadNnn of other tests
4018 if(($log =~ /^curl\d+\.out/) && ($log !~ /^curl$testnum\.out/)) {
4019 next; # skip curlNnn.out of other tests
4021 if(($log =~ /^test\d+\.txt/) && ($log !~ /^test$testnum\.txt/)) {
4022 next; # skip testNnn.txt of other tests
4024 if(($log =~ /^file\d+\.txt/) && ($log !~ /^file$testnum\.txt/)) {
4025 next; # skip fileNnn.txt of other tests
4027 if(($log =~ /^valgrind\d+/) && ($log !~ /^valgrind$testnum(\..*|)$/)) {
4028 next; # skip valgrindNnn of other tests
4030 logmsg "=== Start of file $log\n";
4031 displaylogcontent("$LOGDIR/$log");
4032 logmsg "=== End of file $log\n";
4036 #######################################################################
4037 # The main test-loop
4045 my @at = split(" ", $TESTCASES);
4050 foreach $testnum (@at) {
4052 $lasttest = $testnum if($testnum > $lasttest);
4055 my $error = singletest($testnum, $count, scalar(@at));
4057 # not a test we can run
4061 $total++; # number of tests we've run
4064 $failed.= "$testnum ";
4066 # display all files in log/ in a nice way
4067 displaylogs($testnum);
4070 # a test failed, abort
4071 logmsg "\n - abort tests\n";
4076 $ok++; # successful test counter
4079 # loop for next test
4082 my $sofar = time() - $start;
4084 #######################################################################
4089 # Tests done, stop the servers
4090 stopservers($verbose);
4092 my $all = $total + $skipped;
4094 runtimestats($lasttest);
4097 logmsg sprintf("TESTDONE: $ok tests out of $total reported OK: %d%%\n",
4101 logmsg "TESTFAIL: These test cases failed: $failed\n";
4105 logmsg "TESTFAIL: No tests were performed\n";
4109 logmsg "TESTDONE: $all tests were considered during ".
4110 sprintf("%.0f", $sofar) ." seconds.\n";
4115 logmsg "TESTINFO: $skipped tests were skipped due to these restraints:\n";
4117 for(keys %skipped) {
4119 printf "TESTINFO: \"%s\" %d times (", $r, $skipped{$_};
4121 # now show all test case numbers that had this reason for being
4124 for(0 .. scalar @teststat) {
4126 if($teststat[$_] && ($teststat[$_] eq $r)) {
4136 if($total && ($ok != $total)) {