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
137 my $srcdir = $ENV{'srcdir'} || '.';
138 my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
139 my $VCURL=$CURL; # what curl binary to use to verify the servers with
140 # VCURL is handy to set to the system one when the one you
141 # just built hangs or crashes and thus prevent verification
142 my $DBGCURL=$CURL; #"../src/.libs/curl"; # alternative for debugging
144 my $TESTDIR="$srcdir/data";
145 my $LIBDIR="./libtest";
146 my $SERVERIN="$LOGDIR/server.input"; # what curl sent the server
147 my $SERVER2IN="$LOGDIR/server2.input"; # what curl sent the second server
148 my $CURLLOG="$LOGDIR/curl.log"; # all command lines run
149 my $FTPDCMD="$LOGDIR/ftpserver.cmd"; # copy ftp server instructions here
150 my $SERVERLOGS_LOCK="$LOGDIR/serverlogs.lock"; # server logs advisor read lock
151 my $CURLCONFIG="../curl-config"; # curl-config from current build
153 # Normally, all test cases should be run, but at times it is handy to
154 # simply run a particular one:
157 # To run specific test cases, set them like:
158 # $TESTCASES="1 2 3 7 8";
160 #######################################################################
161 # No variables below this point should need to be modified
164 # invoke perl like this:
165 my $perl="perl -I$srcdir";
166 my $server_response_maxtime=13;
168 my $debug_build=0; # curl built with --enable-debug
169 my $curl_debug=0; # curl built with --enable-curldebug (memory tracking)
172 # name of the file that the memory debugging creates:
173 my $memdump="$LOGDIR/memdump";
175 # the path to the script that analyzes the memory debug output file:
176 my $memanalyze="$perl $srcdir/memanalyze.pl";
178 my $pwd = getcwd(); # current working directory
182 my $ftpchecktime=1; # time it took to verify our test FTP server
184 my $stunnel = checkcmd("stunnel4") || checkcmd("stunnel");
185 my $valgrind = checktestcmd("valgrind");
186 my $valgrind_logfile="--logfile";
188 my $gdb = checktestcmd("gdb");
190 my $ssl_version; # set if libcurl is built with SSL support
191 my $large_file; # set if libcurl is built with large file support
192 my $has_idn; # set if libcurl is built with IDN support
193 my $http_ipv6; # set if HTTP server has IPv6 support
194 my $ftp_ipv6; # set if FTP server has IPv6 support
195 my $tftp_ipv6; # set if TFTP server has IPv6 support
196 my $has_ipv6; # set if libcurl is built with IPv6 support
197 my $has_libz; # set if libcurl is built with libz support
198 my $has_getrlimit; # set if system has getrlimit()
199 my $has_ntlm; # set if libcurl is built with NTLM support
200 my $has_charconv;# set if libcurl is built with CharConv support
202 my $has_openssl; # built with a lib using an OpenSSL-like API
203 my $has_gnutls; # built with GnuTLS
204 my $has_nss; # built with NSS
205 my $has_yassl; # built with yassl
206 my $has_polarssl;# built with polarssl
208 my $has_shared; # built shared
210 my $ssllib; # name of the lib we use (for human presentation)
211 my $has_crypto; # set if libcurl is built with cryptographic support
212 my $has_textaware; # set if running on a system that has a text mode concept
213 # on files. Windows for example
214 my @protocols; # array of supported protocols
216 my $skipped=0; # number of tests skipped; reported in main loop
217 my %skipped; # skipped{reason}=counter, reasons for skip
218 my @teststat; # teststat[testnum]=reason, reasons for skip
219 my %disabled_keywords; # key words of tests to skip
220 my %enabled_keywords; # key words of tests to run
222 my $sshdid; # for socks server, ssh daemon version id
223 my $sshdvernum; # for socks server, ssh daemon version number
224 my $sshdverstr; # for socks server, ssh daemon version string
225 my $sshderror; # for socks server, ssh daemon version error
227 my $defserverlogslocktimeout = 20; # timeout to await server logs lock removal
228 my $defpostcommanddelay = 0; # delay between command and postcheck sections
230 my $timestats; # time stamping and stats generation
231 my $fullstats; # show time stats for every single test
232 my %timeprepini; # timestamp for each test preparation start
233 my %timesrvrini; # timestamp for each test required servers verification start
234 my %timesrvrend; # timestamp for each test required servers verification end
235 my %timetoolini; # timestamp for each test command run starting
236 my %timetoolend; # timestamp for each test command run stopping
237 my %timesrvrlog; # timestamp for each test server logs lock removal
238 my %timevrfyend; # timestamp for each test result verification end
240 my $testnumcheck; # test number, set in singletest sub.
242 #######################################################################
243 # variables the command line options may set
250 my $gdbthis; # run test case with gdb debugger
251 my $keepoutfiles; # keep stdout and stderr files after tests
252 my $listonly; # only list the tests
253 my $postmortem; # display detailed info about failed tests
255 my %run; # running server
256 my %doesntrun; # servers that don't work, identified by pidfile
257 my %serverpidfile;# all server pid file names, identified by server id
258 my %runcert; # cert file currently in use by an ssl running server
260 # torture test variables
265 #######################################################################
266 # logmsg is our general message logging subroutine.
274 # get the name of the current user
275 my $USER = $ENV{USER}; # Linux
277 $USER = $ENV{USERNAME}; # Windows
279 $USER = $ENV{LOGNAME}; # Some UNIX (I think)
283 # enable memory debugging if curl is compiled with it
284 $ENV{'CURL_MEMDEBUG'} = $memdump;
289 logmsg "runtests.pl received SIG$signame, exiting\n";
290 stopservers($verbose);
291 die "Somebody sent me a SIG$signame";
293 $SIG{INT} = \&catch_zap;
294 $SIG{TERM} = \&catch_zap;
296 ##########################################################################
297 # Clear all possible '*_proxy' environment variables for various protocols
298 # to prevent them to interfere with our testing!
301 foreach $protocol (('ftp', 'http', 'ftps', 'https', 'no')) {
302 my $proxy = "${protocol}_proxy";
303 # clear lowercase version
304 delete $ENV{$proxy} if($ENV{$proxy});
305 # clear uppercase version
306 delete $ENV{uc($proxy)} if($ENV{uc($proxy)});
309 # make sure we don't get affected by other variables that control our
312 delete $ENV{'SSL_CERT_DIR'} if($ENV{'SSL_CERT_DIR'});
313 delete $ENV{'SSL_CERT_PATH'} if($ENV{'SSL_CERT_PATH'});
314 delete $ENV{'CURL_CA_BUNDLE'} if($ENV{'CURL_CA_BUNDLE'});
316 #######################################################################
317 # Load serverpidfile hash with pidfile names for all possible servers.
319 sub init_serverpidfile_hash {
320 for my $proto (('ftp', 'http', 'imap', 'pop3', 'smtp')) {
321 for my $ssl (('', 's')) {
322 for my $ipvnum ((4, 6)) {
323 for my $idnum ((1, 2)) {
324 my $serv = servername_id("$proto$ssl", $ipvnum, $idnum);
325 my $pidf = server_pidfilename("$proto$ssl", $ipvnum, $idnum);
326 $serverpidfile{$serv} = $pidf;
331 for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp')) {
332 for my $ipvnum ((4, 6)) {
333 for my $idnum ((1, 2)) {
334 my $serv = servername_id($proto, $ipvnum, $idnum);
335 my $pidf = server_pidfilename($proto, $ipvnum, $idnum);
336 $serverpidfile{$serv} = $pidf;
342 #######################################################################
343 # Check if a given child process has just died. Reaps it if so.
346 use POSIX ":sys_wait_h";
348 if(not defined $pid || $pid <= 0) {
351 my $rc = waitpid($pid, &WNOHANG);
352 return ($rc == $pid)?1:0;
355 #######################################################################
356 # Start a new thread/process and run the given command line in there.
357 # Return the pids (yes plural) of the new child process to the parent.
360 my ($cmd, $pidfile, $timeout, $fake)=@_;
362 logmsg "startnew: $cmd\n" if ($verbose);
367 if(not defined $child) {
368 logmsg "startnew: fork() failure detected\n";
373 # Here we are the child. Run the given command.
375 # Put an "exec" in front of the command so that the child process
376 # keeps this child's process ID.
377 exec("exec $cmd") || die "Can't exec() $cmd: $!";
379 # exec() should never return back here to this process. We protect
380 # ourselves by calling die() just in case something goes really bad.
381 die "error: exec() has returned";
384 # Ugly hack but ssh client doesn't support pid files
386 if(open(OUT, ">$pidfile")) {
387 print OUT $child . "\n";
389 logmsg "startnew: $pidfile faked with pid=$child\n" if($verbose);
392 logmsg "startnew: failed to write fake $pidfile with pid=$child\n";
394 # could/should do a while connect fails sleep a bit and loop
396 if (checkdied($child)) {
397 logmsg "startnew: child process has failed to start\n" if($verbose);
402 my $count = $timeout;
404 if(-f $pidfile && -s $pidfile && open(PID, "<$pidfile")) {
407 if(($pid2 > 0) && kill(0, $pid2)) {
408 # if $pid2 is valid, then make sure this pid is alive, as
409 # otherwise it is just likely to be the _previous_ pidfile or
413 # invalidate $pid2 if not actually alive
416 if (checkdied($child)) {
417 logmsg "startnew: child process has died, server might start up\n"
419 # We can't just abort waiting for the server with a
421 # because the server might have forked and could still start
422 # up normally. Instead, just reduce the amount of time we remain
429 # Return two PIDs, the one for the child process we spawned and the one
430 # reported by the server itself (in case it forked again on its own).
431 # Both (potentially) need to be killed at the end of the test.
432 return ($child, $pid2);
436 #######################################################################
437 # Check for a command in the PATH of the test server.
441 my @paths=(split(":", $ENV{'PATH'}), "/usr/sbin", "/usr/local/sbin",
442 "/sbin", "/usr/bin", "/usr/local/bin",
443 "./libtest/.libs", "./libtest");
445 if( -x "$_/$cmd" && ! -d "$_/$cmd") {
446 # executable bit but not a directory!
452 #######################################################################
453 # Get the list of tests that the tests/data/Makefile.am knows about!
457 my @dist = `cd data && make show`;
458 $disttests = join("", @dist);
461 #######################################################################
462 # Check for a command in the PATH of the machine running curl.
466 return checkcmd($cmd);
469 #######################################################################
470 # Run the application under test and return its return code
476 # This is one way to test curl on a remote machine
477 # my $out = system("ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'");
478 # sleep 2; # time to allow the NFS server to be updated
482 #######################################################################
483 # Run the application under test and return its stdout
485 sub runclientoutput {
489 # This is one way to test curl on a remote machine
490 # my @out = `ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'`;
491 # sleep 2; # time to allow the NFS server to be updated
495 #######################################################################
496 # Memory allocation test and failure torture testing.
502 # remove memdump first to be sure we get a new nice and clean one
505 # First get URL from test server, ignore the output/result
508 logmsg " CMD: $testcmd\n" if($verbose);
510 # memanalyze -v is our friend, get the number of allocations made
512 my @out = `$memanalyze -v $memdump`;
514 if(/^Allocations: (\d+)/) {
520 logmsg " found no allocs to make fail\n";
524 logmsg " $count allocations to make fail\n";
526 for ( 1 .. $count ) {
531 if($tortalloc && ($tortalloc != $limit)) {
536 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
538 my $now = sprintf("%02d:%02d:%02d ", $hour, $min, $sec);
539 logmsg "Fail alloc no: $limit at $now\r";
542 # make the memory allocation function number $limit return failure
543 $ENV{'CURL_MEMLIMIT'} = $limit;
545 # remove memdump first to be sure we get a new nice and clean one
548 logmsg "*** Alloc number $limit is now set to fail ***\n" if($gdbthis);
555 $ret = runclient($testcmd);
557 #logmsg "$_ Returned " . $ret >> 8 . "\n";
559 # Now clear the variable again
560 delete $ENV{'CURL_MEMLIMIT'} if($ENV{'CURL_MEMLIMIT'});
563 # there's core file present now!
564 logmsg " core dumped\n";
569 # verify that it returns a proper error code, doesn't leak memory
570 # and doesn't core dump
572 logmsg " system() returned $ret\n";
576 my @memdata=`$memanalyze $memdump`;
580 # well it could be other memory problems as well, but
581 # we call it leak for short here
586 logmsg "** MEMORY FAILURE\n";
588 logmsg `$memanalyze -l $memdump`;
593 logmsg " Failed on alloc number $limit in test.\n",
594 " invoke with \"-t$limit\" to repeat this single case.\n";
595 stopservers($verbose);
600 logmsg "torture OK\n";
604 #######################################################################
605 # Stop a test server along with pids which aren't in the %run hash yet.
606 # This also stops all servers which are relative to the given one.
609 my ($server, $pidlist) = @_;
611 # kill sockfilter processes for pingpong relative server
613 if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
615 my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
616 my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
617 killsockfilters($proto, $ipvnum, $idnum, $verbose);
620 # All servers relative to the given one must be stopped also
623 if($server =~ /^(ftp|http|imap|pop3|smtp)s(.*)$/) {
624 # given an ssl server, also kill non-ssl underlying one
625 push @killservers, "${1}${2}";
627 elsif($server =~ /^(ftp|http|imap|pop3|smtp)(.*)$/) {
628 # given a non-ssl server, also kill ssl piggybacking one
629 push @killservers, "${1}s${2}";
631 elsif($server =~ /^(socks)(.*)$/) {
632 # given an socks server, also kill ssh underlying one
633 push @killservers, "ssh${2}";
635 elsif($server =~ /^(ssh)(.*)$/) {
636 # given an ssh server, also kill socks piggybacking one
637 push @killservers, "socks${2}";
639 push @killservers, $server;
641 # kill given pids and server relative ones clearing them in %run hash
643 foreach my $server (@killservers) {
645 $pidlist .= "$run{$server} ";
648 $runcert{$server} = 0 if($runcert{$server});
650 killpid($verbose, $pidlist);
652 # cleanup server pid files
654 foreach my $server (@killservers) {
655 my $pidfile = $serverpidfile{$server};
656 my $pid = processexists($pidfile);
658 logmsg "Warning: $server server unexpectedly alive\n";
659 killpid($verbose, $pid);
661 unlink($pidfile) if(-f $pidfile);
665 #######################################################################
666 # Verify that the server that runs on $ip, $port is our server. This also
667 # implies that we can speak with it, as there might be occasions when the
668 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
669 # assign requested address" #
672 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
673 my $server = servername_id($proto, $ipvnum, $idnum);
676 my $verifyout = "$LOGDIR/".
677 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
678 unlink($verifyout) if(-f $verifyout);
680 my $verifylog = "$LOGDIR/".
681 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
682 unlink($verifylog) if(-f $verifylog);
684 my $flags = "--max-time $server_response_maxtime ";
685 $flags .= "--output $verifyout ";
686 $flags .= "--silent ";
687 $flags .= "--verbose ";
688 $flags .= "--globoff ";
689 $flags .= "--insecure " if($proto eq 'https');
690 $flags .= "\"$proto://$ip:$port/verifiedserver\"";
692 my $cmd = "$VCURL $flags 2>$verifylog";
694 # verify if our/any server is running on this port
695 logmsg "RUN: $cmd\n" if($verbose);
696 my $res = runclient($cmd);
698 $res >>= 8; # rotate the result
700 logmsg "RUN: curl command died with a coredump\n";
704 if($res && $verbose) {
705 logmsg "RUN: curl command returned $res\n";
706 if(open(FILE, "<$verifylog")) {
707 while(my $string = <FILE>) {
708 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
715 if(open(FILE, "<$verifyout")) {
716 while(my $string = <FILE>) {
718 last; # only want first line
723 if($data && ($data =~ /WE ROOLZ: (\d+)/)) {
727 # curl: (6) Couldn't resolve host '::1'
728 logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
731 elsif($data || ($res != 7)) {
732 logmsg "RUN: Unknown server on our $server port: $port\n";
738 #######################################################################
739 # Verify that the server that runs on $ip, $port is our server. This also
740 # implies that we can speak with it, as there might be occasions when the
741 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
742 # assign requested address" #
745 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
746 my $server = servername_id($proto, $ipvnum, $idnum);
751 my $verifylog = "$LOGDIR/".
752 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
753 unlink($verifylog) if(-f $verifylog);
755 if($proto eq "ftps") {
756 $extra .= "--insecure --ftp-ssl-control ";
758 elsif($proto eq "smtp") {
759 # SMTP is a bit different since it requires more options and it
761 $extra .= "--mail-rcpt verifiedserver ";
762 $extra .= "--mail-from fake ";
763 $extra .= "--upload /dev/null ";
764 $extra .= "--stderr - "; # move stderr to parse the verbose stuff
767 my $flags = "--max-time $server_response_maxtime ";
768 $flags .= "--silent ";
769 $flags .= "--verbose ";
770 $flags .= "--globoff ";
772 $flags .= "\"$proto://$ip:$port/verifiedserver\"";
774 my $cmd = "$VCURL $flags 2>$verifylog";
776 # check if this is our server running on this port:
777 logmsg "RUN: $cmd\n" if($verbose);
778 my @data = runclientoutput($cmd);
780 my $res = $? >> 8; # rotate the result
782 logmsg "RUN: curl command died with a coredump\n";
786 foreach my $line (@data) {
787 if($line =~ /WE ROOLZ: (\d+)/) {
788 # this is our test server with a known pid!
793 if($pid <= 0 && @data && $data[0]) {
794 # this is not a known server
795 logmsg "RUN: Unknown server on our $server port: $port\n";
798 # we can/should use the time it took to verify the FTP server as a measure
799 # on how fast/slow this host/FTP is.
800 my $took = int(0.5+time()-$time);
803 logmsg "RUN: Verifying our test $server server took $took seconds\n";
805 $ftpchecktime = $took>=1?$took:1; # make sure it never is below 1
810 #######################################################################
811 # Verify that the server that runs on $ip, $port is our server. This also
812 # implies that we can speak with it, as there might be occasions when the
813 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
814 # assign requested address" #
817 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
818 my $server = servername_id($proto, $ipvnum, $idnum);
821 my $verifyout = "$LOGDIR/".
822 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
823 unlink($verifyout) if(-f $verifyout);
825 my $verifylog = "$LOGDIR/".
826 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
827 unlink($verifylog) if(-f $verifylog);
829 my $flags = "--max-time $server_response_maxtime ";
830 $flags .= "--output $verifyout ";
831 $flags .= "--silent ";
832 $flags .= "--verbose ";
833 $flags .= "--globoff ";
834 # currently verification is done using http
835 $flags .= "\"http://$ip:$port/verifiedserver\"";
837 my $cmd = "$VCURL $flags 2>$verifylog";
839 # verify if our/any server is running on this port
840 logmsg "RUN: $cmd\n" if($verbose);
841 my $res = runclient($cmd);
843 $res >>= 8; # rotate the result
845 logmsg "RUN: curl command died with a coredump\n";
849 if($res && $verbose) {
850 logmsg "RUN: curl command returned $res\n";
851 if(open(FILE, "<$verifylog")) {
852 while(my $string = <FILE>) {
853 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
860 if(open(FILE, "<$verifyout")) {
861 while(my $string = <FILE>) {
863 last; # only want first line
868 if($data && ($data =~ /RTSP_SERVER WE ROOLZ: (\d+)/)) {
872 # curl: (6) Couldn't resolve host '::1'
873 logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
876 elsif($data || ($res != 7)) {
877 logmsg "RUN: Unknown server on our $server port: $port\n";
883 #######################################################################
884 # Verify that the ssh server has written out its pidfile, recovering
885 # the pid from the file and returning it if a process with that pid is
889 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
890 my $server = servername_id($proto, $ipvnum, $idnum);
891 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
893 if(open(FILE, "<$pidfile")) {
898 # if we have a pid it is actually our ssh server,
899 # since runsshserver() unlinks previous pidfile
901 logmsg "RUN: SSH server has died after starting up\n";
910 #######################################################################
911 # Verify that we can connect to the sftp server, properly authenticate
912 # with generated config and key files and run a simple remote pwd.
915 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
916 my $server = servername_id($proto, $ipvnum, $idnum);
918 # Find out sftp client canonical file name
919 my $sftp = find_sftp();
921 logmsg "RUN: SFTP server cannot find $sftpexe\n";
924 # Find out ssh client canonical file name
925 my $ssh = find_ssh();
927 logmsg "RUN: SFTP server cannot find $sshexe\n";
930 # Connect to sftp server, authenticate and run a remote pwd
931 # command using our generated configuration and key files
932 my $cmd = "$sftp -b $sftpcmds -F $sftpconfig -S $ssh $ip > $sftplog 2>&1";
933 my $res = runclient($cmd);
934 # Search for pwd command response in log file
935 if(open(SFTPLOGFILE, "<$sftplog")) {
936 while(<SFTPLOGFILE>) {
937 if(/^Remote working directory: /) {
948 #######################################################################
949 # STUB for verifying socks
952 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
953 my $server = servername_id($proto, $ipvnum, $idnum);
954 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
956 if(open(FILE, "<$pidfile")) {
961 # if we have a pid it is actually our socks server,
962 # since runsocksserver() unlinks previous pidfile
964 logmsg "RUN: SOCKS server has died after starting up\n";
973 #######################################################################
974 # Verify that the server that runs on $ip, $port is our server.
975 # Retry over several seconds before giving up. The ssh server in
976 # particular can take a long time to start if it needs to generate
977 # keys on a slow or loaded host.
980 my %protofunc = ('http' => \&verifyhttp,
981 'https' => \&verifyhttp,
982 'rtsp' => \&verifyrtsp,
983 'ftp' => \&verifyftp,
984 'pop3' => \&verifyftp,
985 'imap' => \&verifyftp,
986 'smtp' => \&verifyftp,
987 'ftps' => \&verifyftp,
988 'tftp' => \&verifyftp,
989 'ssh' => \&verifyssh,
990 'socks' => \&verifysocks);
993 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
995 my $count = 30; # try for this many seconds
999 my $fun = $protofunc{$proto};
1001 $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port);
1007 # a real failure, stop trying and bail out
1017 #######################################################################
1018 # start the http server
1021 my ($verbose, $ipv6) = @_;
1022 my $port = $HTTPPORT;
1034 # if IPv6, use a different setup
1040 $server = servername_id($proto, $ipvnum, $idnum);
1042 $pidfile = $serverpidfile{$server};
1044 # don't retry if the server doesn't work
1045 if ($doesntrun{$pidfile}) {
1049 my $pid = processexists($pidfile);
1051 stopserver($server, "$pid");
1053 unlink($pidfile) if(-f $pidfile);
1055 $srvrname = servername_str($proto, $ipvnum, $idnum);
1057 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1059 $flags .= "--fork " if($forkserver);
1060 $flags .= "--verbose " if($debugprotocol);
1061 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1062 $flags .= "--id $idnum " if($idnum > 1);
1063 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1065 my $cmd = "$perl $srcdir/httpserver.pl $flags";
1066 my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1068 if($httppid <= 0 || !kill(0, $httppid)) {
1070 logmsg "RUN: failed to start the $srvrname server\n";
1071 stopserver($server, "$pid2");
1072 displaylogs($testnumcheck);
1073 $doesntrun{$pidfile} = 1;
1077 # Server is up. Verify that we can speak to it.
1078 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1080 logmsg "RUN: $srvrname server failed verification\n";
1081 # failed to talk to it properly. Kill the server and return failure
1082 stopserver($server, "$httppid $pid2");
1083 displaylogs($testnumcheck);
1084 $doesntrun{$pidfile} = 1;
1090 logmsg "RUN: $srvrname server is now running PID $httppid\n";
1095 return ($httppid, $pid2);
1098 #######################################################################
1099 # start the https server (or rather, tunnel)
1101 sub runhttpsserver {
1102 my ($verbose, $ipv6, $certfile) = @_;
1103 my $proto = 'https';
1104 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1105 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1117 $server = servername_id($proto, $ipvnum, $idnum);
1119 $pidfile = $serverpidfile{$server};
1121 # don't retry if the server doesn't work
1122 if ($doesntrun{$pidfile}) {
1126 my $pid = processexists($pidfile);
1128 stopserver($server, "$pid");
1130 unlink($pidfile) if(-f $pidfile);
1132 $srvrname = servername_str($proto, $ipvnum, $idnum);
1134 $certfile = 'stunnel.pem' unless($certfile);
1136 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1138 $flags .= "--verbose " if($debugprotocol);
1139 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1140 $flags .= "--id $idnum " if($idnum > 1);
1141 $flags .= "--ipv$ipvnum --proto $proto ";
1142 $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
1143 $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
1144 $flags .= "--connect $HTTPPORT --accept $HTTPSPORT";
1146 my $cmd = "$perl $srcdir/secureserver.pl $flags";
1147 my ($httpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1149 if($httpspid <= 0 || !kill(0, $httpspid)) {
1151 logmsg "RUN: failed to start the $srvrname server\n";
1152 stopserver($server, "$pid2");
1153 displaylogs($testnumcheck);
1154 $doesntrun{$pidfile} = 1;
1158 # Server is up. Verify that we can speak to it.
1159 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $HTTPSPORT);
1161 logmsg "RUN: $srvrname server failed verification\n";
1162 # failed to talk to it properly. Kill the server and return failure
1163 stopserver($server, "$httpspid $pid2");
1164 displaylogs($testnumcheck);
1165 $doesntrun{$pidfile} = 1;
1168 # Here pid3 is actually the pid returned by the unsecure-http server.
1170 $runcert{$server} = $certfile;
1173 logmsg "RUN: $srvrname server is now running PID $httpspid\n";
1178 return ($httpspid, $pid2);
1181 #######################################################################
1182 # start the pingpong server (FTP, POP3, IMAP, SMTP)
1184 sub runpingpongserver {
1185 my ($proto, $id, $verbose, $ipv6) = @_;
1187 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1188 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1189 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1196 if($proto eq "ftp") {
1197 $port = ($idnum>1)?$FTP2PORT:$FTPPORT;
1200 # if IPv6, use a different setup
1204 elsif($proto eq "pop3") {
1205 $port = ($ipvnum==6) ? $POP36PORT : $POP3PORT;
1207 elsif($proto eq "imap") {
1208 $port = ($ipvnum==6) ? $IMAP6PORT : $IMAPPORT;
1210 elsif($proto eq "smtp") {
1211 $port = ($ipvnum==6) ? $SMTP6PORT : $SMTPPORT;
1214 print STDERR "Unsupported protocol $proto!!\n";
1218 $server = servername_id($proto, $ipvnum, $idnum);
1220 $pidfile = $serverpidfile{$server};
1222 # don't retry if the server doesn't work
1223 if ($doesntrun{$pidfile}) {
1227 my $pid = processexists($pidfile);
1229 stopserver($server, "$pid");
1231 unlink($pidfile) if(-f $pidfile);
1233 $srvrname = servername_str($proto, $ipvnum, $idnum);
1235 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1237 $flags .= "--verbose " if($debugprotocol);
1238 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1239 $flags .= "--srcdir \"$srcdir\" --proto $proto ";
1240 $flags .= "--id $idnum " if($idnum > 1);
1241 $flags .= "--ipv$ipvnum --port $port --addr \"$ip\"";
1243 my $cmd = "$perl $srcdir/ftpserver.pl $flags";
1244 my ($ftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1246 if($ftppid <= 0 || !kill(0, $ftppid)) {
1248 logmsg "RUN: failed to start the $srvrname server\n";
1249 stopserver($server, "$pid2");
1250 displaylogs($testnumcheck);
1251 $doesntrun{$pidfile} = 1;
1255 # Server is up. Verify that we can speak to it.
1256 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1258 logmsg "RUN: $srvrname server failed verification\n";
1259 # failed to talk to it properly. Kill the server and return failure
1260 stopserver($server, "$ftppid $pid2");
1261 displaylogs($testnumcheck);
1262 $doesntrun{$pidfile} = 1;
1268 logmsg "RUN: $srvrname server is now running PID $ftppid\n";
1273 return ($pid2, $ftppid);
1276 #######################################################################
1277 # start the ftps server (or rather, tunnel)
1280 my ($verbose, $ipv6, $certfile) = @_;
1282 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1283 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1295 $server = servername_id($proto, $ipvnum, $idnum);
1297 $pidfile = $serverpidfile{$server};
1299 # don't retry if the server doesn't work
1300 if ($doesntrun{$pidfile}) {
1304 my $pid = processexists($pidfile);
1306 stopserver($server, "$pid");
1308 unlink($pidfile) if(-f $pidfile);
1310 $srvrname = servername_str($proto, $ipvnum, $idnum);
1312 $certfile = 'stunnel.pem' unless($certfile);
1314 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1316 $flags .= "--verbose " if($debugprotocol);
1317 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1318 $flags .= "--id $idnum " if($idnum > 1);
1319 $flags .= "--ipv$ipvnum --proto $proto ";
1320 $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
1321 $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
1322 $flags .= "--connect $FTPPORT --accept $FTPSPORT";
1324 my $cmd = "$perl $srcdir/secureserver.pl $flags";
1325 my ($ftpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1327 if($ftpspid <= 0 || !kill(0, $ftpspid)) {
1329 logmsg "RUN: failed to start the $srvrname server\n";
1330 stopserver($server, "$pid2");
1331 displaylogs($testnumcheck);
1332 $doesntrun{$pidfile} = 1;
1336 # Server is up. Verify that we can speak to it.
1337 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $FTPSPORT);
1339 logmsg "RUN: $srvrname server failed verification\n";
1340 # failed to talk to it properly. Kill the server and return failure
1341 stopserver($server, "$ftpspid $pid2");
1342 displaylogs($testnumcheck);
1343 $doesntrun{$pidfile} = 1;
1346 # Here pid3 is actually the pid returned by the unsecure-ftp server.
1348 $runcert{$server} = $certfile;
1351 logmsg "RUN: $srvrname server is now running PID $ftpspid\n";
1356 return ($ftpspid, $pid2);
1359 #######################################################################
1360 # start the tftp server
1363 my ($id, $verbose, $ipv6) = @_;
1364 my $port = $TFTPPORT;
1368 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1376 # if IPv6, use a different setup
1382 $server = servername_id($proto, $ipvnum, $idnum);
1384 $pidfile = $serverpidfile{$server};
1386 # don't retry if the server doesn't work
1387 if ($doesntrun{$pidfile}) {
1391 my $pid = processexists($pidfile);
1393 stopserver($server, "$pid");
1395 unlink($pidfile) if(-f $pidfile);
1397 $srvrname = servername_str($proto, $ipvnum, $idnum);
1399 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1401 $flags .= "--verbose " if($debugprotocol);
1402 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1403 $flags .= "--id $idnum " if($idnum > 1);
1404 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1406 my $cmd = "$perl $srcdir/tftpserver.pl $flags";
1407 my ($tftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1409 if($tftppid <= 0 || !kill(0, $tftppid)) {
1411 logmsg "RUN: failed to start the $srvrname server\n";
1412 stopserver($server, "$pid2");
1413 displaylogs($testnumcheck);
1414 $doesntrun{$pidfile} = 1;
1418 # Server is up. Verify that we can speak to it.
1419 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1421 logmsg "RUN: $srvrname server failed verification\n";
1422 # failed to talk to it properly. Kill the server and return failure
1423 stopserver($server, "$tftppid $pid2");
1424 displaylogs($testnumcheck);
1425 $doesntrun{$pidfile} = 1;
1431 logmsg "RUN: $srvrname server is now running PID $tftppid\n";
1436 return ($pid2, $tftppid);
1440 #######################################################################
1441 # start the rtsp server
1444 my ($verbose, $ipv6) = @_;
1445 my $port = $RTSPPORT;
1457 # if IPv6, use a different setup
1463 $server = servername_id($proto, $ipvnum, $idnum);
1465 $pidfile = $serverpidfile{$server};
1467 # don't retry if the server doesn't work
1468 if ($doesntrun{$pidfile}) {
1472 my $pid = processexists($pidfile);
1474 stopserver($server, "$pid");
1476 unlink($pidfile) if(-f $pidfile);
1478 $srvrname = servername_str($proto, $ipvnum, $idnum);
1480 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1482 $flags .= "--verbose " if($debugprotocol);
1483 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1484 $flags .= "--id $idnum " if($idnum > 1);
1485 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1487 my $cmd = "$perl $srcdir/rtspserver.pl $flags";
1488 my ($rtsppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1490 if($rtsppid <= 0 || !kill(0, $rtsppid)) {
1492 logmsg "RUN: failed to start the $srvrname server\n";
1493 stopserver($server, "$pid2");
1494 displaylogs($testnumcheck);
1495 $doesntrun{$pidfile} = 1;
1499 # Server is up. Verify that we can speak to it.
1500 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1502 logmsg "RUN: $srvrname server failed verification\n";
1503 # failed to talk to it properly. Kill the server and return failure
1504 stopserver($server, "$rtsppid $pid2");
1505 displaylogs($testnumcheck);
1506 $doesntrun{$pidfile} = 1;
1512 logmsg "RUN: $srvrname server is now running PID $rtsppid\n";
1517 return ($rtsppid, $pid2);
1521 #######################################################################
1522 # Start the ssh (scp/sftp) server
1525 my ($id, $verbose, $ipv6) = @_;
1527 my $port = $SSHPORT;
1528 my $socksport = $SOCKSPORT;
1531 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1538 $server = servername_id($proto, $ipvnum, $idnum);
1540 $pidfile = $serverpidfile{$server};
1542 # don't retry if the server doesn't work
1543 if ($doesntrun{$pidfile}) {
1547 my $pid = processexists($pidfile);
1549 stopserver($server, "$pid");
1551 unlink($pidfile) if(-f $pidfile);
1553 $srvrname = servername_str($proto, $ipvnum, $idnum);
1555 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1557 $flags .= "--verbose " if($verbose);
1558 $flags .= "--debugprotocol " if($debugprotocol);
1559 $flags .= "--pidfile \"$pidfile\" ";
1560 $flags .= "--id $idnum " if($idnum > 1);
1561 $flags .= "--ipv$ipvnum --addr \"$ip\" ";
1562 $flags .= "--sshport $port --socksport $socksport ";
1563 $flags .= "--user \"$USER\"";
1565 my $cmd = "$perl $srcdir/sshserver.pl $flags";
1566 my ($sshpid, $pid2) = startnew($cmd, $pidfile, 60, 0);
1568 # on loaded systems sshserver start up can take longer than the timeout
1569 # passed to startnew, when this happens startnew completes without being
1570 # able to read the pidfile and consequently returns a zero pid2 above.
1572 if($sshpid <= 0 || !kill(0, $sshpid)) {
1574 logmsg "RUN: failed to start the $srvrname server\n";
1575 stopserver($server, "$pid2");
1576 $doesntrun{$pidfile} = 1;
1580 # ssh server verification allows some extra time for the server to start up
1581 # and gives us the opportunity of recovering the pid from the pidfile, when
1582 # this verification succeeds the recovered pid is assigned to pid2.
1584 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1586 logmsg "RUN: $srvrname server failed verification\n";
1587 # failed to fetch server pid. Kill the server and return failure
1588 stopserver($server, "$sshpid $pid2");
1589 $doesntrun{$pidfile} = 1;
1594 # once it is known that the ssh server is alive, sftp server verification
1595 # is performed actually connecting to it, authenticating and performing a
1596 # very simple remote command. This verification is tried only one time.
1598 $sshdlog = server_logfilename($LOGDIR, 'ssh', $ipvnum, $idnum);
1599 $sftplog = server_logfilename($LOGDIR, 'sftp', $ipvnum, $idnum);
1601 if(verifysftp('sftp', $ipvnum, $idnum, $ip, $port) < 1) {
1602 logmsg "RUN: SFTP server failed verification\n";
1603 # failed to talk to it properly. Kill the server and return failure
1605 display_sftpconfig();
1607 display_sshdconfig();
1608 stopserver($server, "$sshpid $pid2");
1609 $doesntrun{$pidfile} = 1;
1614 logmsg "RUN: $srvrname server is now running PID $pid2\n";
1617 return ($pid2, $sshpid);
1620 #######################################################################
1621 # Start the socks server
1623 sub runsocksserver {
1624 my ($id, $verbose, $ipv6) = @_;
1626 my $port = $SOCKSPORT;
1627 my $proto = 'socks';
1629 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1636 $server = servername_id($proto, $ipvnum, $idnum);
1638 $pidfile = $serverpidfile{$server};
1640 # don't retry if the server doesn't work
1641 if ($doesntrun{$pidfile}) {
1645 my $pid = processexists($pidfile);
1647 stopserver($server, "$pid");
1649 unlink($pidfile) if(-f $pidfile);
1651 $srvrname = servername_str($proto, $ipvnum, $idnum);
1653 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1655 # The ssh server must be already running
1657 logmsg "RUN: SOCKS server cannot find running SSH server\n";
1658 $doesntrun{$pidfile} = 1;
1662 # Find out ssh daemon canonical file name
1663 my $sshd = find_sshd();
1665 logmsg "RUN: SOCKS server cannot find $sshdexe\n";
1666 $doesntrun{$pidfile} = 1;
1670 # Find out ssh daemon version info
1671 ($sshdid, $sshdvernum, $sshdverstr, $sshderror) = sshversioninfo($sshd);
1673 # Not an OpenSSH or SunSSH ssh daemon
1674 logmsg "$sshderror\n" if($verbose);
1675 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
1676 $doesntrun{$pidfile} = 1;
1679 logmsg "ssh server found $sshd is $sshdverstr\n" if($verbose);
1681 # Find out ssh client canonical file name
1682 my $ssh = find_ssh();
1684 logmsg "RUN: SOCKS server cannot find $sshexe\n";
1685 $doesntrun{$pidfile} = 1;
1689 # Find out ssh client version info
1690 my ($sshid, $sshvernum, $sshverstr, $ssherror) = sshversioninfo($ssh);
1692 # Not an OpenSSH or SunSSH ssh client
1693 logmsg "$ssherror\n" if($verbose);
1694 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
1695 $doesntrun{$pidfile} = 1;
1699 # Verify minimum ssh client version
1700 if((($sshid =~ /OpenSSH/) && ($sshvernum < 299)) ||
1701 (($sshid =~ /SunSSH/) && ($sshvernum < 100))) {
1702 logmsg "ssh client found $ssh is $sshverstr\n";
1703 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
1704 $doesntrun{$pidfile} = 1;
1707 logmsg "ssh client found $ssh is $sshverstr\n" if($verbose);
1709 # Verify if ssh client and ssh daemon versions match
1710 if(($sshdid ne $sshid) || ($sshdvernum != $sshvernum)) {
1711 # Our test harness might work with slightly mismatched versions
1712 logmsg "Warning: version mismatch: sshd $sshdverstr - ssh $sshverstr\n"
1716 # Config file options for ssh client are previously set from sshserver.pl
1717 if(! -e $sshconfig) {
1718 logmsg "RUN: SOCKS server cannot find $sshconfig\n";
1719 $doesntrun{$pidfile} = 1;
1723 $sshlog = server_logfilename($LOGDIR, 'socks', $ipvnum, $idnum);
1725 # start our socks server
1726 my $cmd="$ssh -N -F $sshconfig $ip > $sshlog 2>&1";
1727 my ($sshpid, $pid2) = startnew($cmd, $pidfile, 30, 1);
1729 if($sshpid <= 0 || !kill(0, $sshpid)) {
1731 logmsg "RUN: failed to start the $srvrname server\n";
1733 display_sshconfig();
1735 display_sshdconfig();
1736 stopserver($server, "$pid2");
1737 $doesntrun{$pidfile} = 1;
1741 # Ugly hack but ssh doesn't support pid files
1742 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1744 logmsg "RUN: $srvrname server failed verification\n";
1745 # failed to talk to it properly. Kill the server and return failure
1746 stopserver($server, "$sshpid $pid2");
1747 $doesntrun{$pidfile} = 1;
1753 logmsg "RUN: $srvrname server is now running PID $pid2\n";
1756 return ($pid2, $sshpid);
1759 #######################################################################
1760 # Remove all files in the specified directory
1768 opendir(DIR, $dir) ||
1769 return 0; # can't open dir
1770 while($file = readdir(DIR)) {
1771 if($file !~ /^\./) {
1772 unlink("$dir/$file");
1780 #######################################################################
1781 # filter out the specified pattern from the given input file and store the
1782 # results in the given output file
1789 open(IN, "<$infile")
1792 open(OUT, ">$ofile")
1795 # logmsg "FILTER: off $filter from $infile to $ofile\n";
1806 #######################################################################
1807 # compare test results with the expected output, we might filter off
1808 # some pattern that is allowed to differ, output test results
1812 # filter off patterns _before_ this comparison!
1813 my ($subject, $firstref, $secondref)=@_;
1815 my $result = compareparts($firstref, $secondref);
1819 logmsg "\n $subject FAILED:\n";
1820 logmsg showdiff($LOGDIR, $firstref, $secondref);
1829 #######################################################################
1830 # display information about curl and the host the test suite runs on
1834 unlink($memdump); # remove this if there was one left
1843 my $curlverout="$LOGDIR/curlverout.log";
1844 my $curlvererr="$LOGDIR/curlvererr.log";
1845 my $versioncmd="$CURL --version 1>$curlverout 2>$curlvererr";
1847 unlink($curlverout);
1848 unlink($curlvererr);
1850 $versretval = runclient($versioncmd);
1853 open(VERSOUT, "<$curlverout");
1854 @version = <VERSOUT>;
1862 $curl =~ s/^(.*)(libcurl.*)/$1/g;
1865 if($curl =~ /mingw32/) {
1866 # This is a windows minw32 build, we need to translate the
1867 # given path to the "actual" windows path.
1874 # example mount output:
1875 # C:\DOCUME~1\Temp on /tmp type user (binmode,noumount)
1876 # c:\ActiveState\perl on /perl type user (binmode)
1877 # C:\msys\1.0\bin on /usr/bin type user (binmode,cygexec,noumount)
1878 # C:\msys\1.0\bin on /bin type user (binmode,cygexec,noumount)
1880 foreach $mount (@m) {
1881 if( $mount =~ /(.*) on ([^ ]*) type /) {
1882 my ($mingw, $real)=($2, $1);
1883 if($pwd =~ /^$mingw/) {
1884 # the path we got from pwd starts with the path
1885 # we found on this line in the mount output
1887 my $len = length($real);
1888 if($len > $matchlen) {
1889 # we remember the match that is the longest
1897 logmsg "Serious error, can't find our \"real\" path\n";
1900 # now prepend the prefix from the mount command to build
1902 $pwd = "$bestmatch$pwd";
1906 elsif ($curl =~ /win32/) {
1907 # Native Windows builds don't understand the
1908 # output of cygwin's pwd. It will be
1909 # something like /cygdrive/c/<some path>.
1911 # Use the cygpath utility to convert the
1912 # working directory to a Windows friendly
1913 # path. The -m option converts to use drive
1914 # letter:, but it uses / instead \. Forward
1915 # slashes (/) are easier for us. We don't
1916 # have to escape them to get them to curl
1918 chomp($pwd = `cygpath -m $pwd`);
1920 elsif ($libcurl =~ /openssl/i) {
1924 elsif ($libcurl =~ /gnutls/i) {
1928 elsif ($libcurl =~ /nss/i) {
1932 elsif ($libcurl =~ /yassl/i) {
1937 elsif ($libcurl =~ /polarssl/i) {
1943 elsif($_ =~ /^Protocols: (.*)/i) {
1944 # these are the protocols compiled in to this libcurl
1945 @protocols = split(' ', $1);
1947 # Generate a "proto-ipv6" version of each protocol to match the
1948 # IPv6 <server> name. This works even if IPv6 support isn't
1949 # compiled in because the <features> test will fail.
1950 push @protocols, map($_ . "-ipv6", @protocols);
1952 # 'none' is used in test cases to mean no server
1953 push @protocols, ('none');
1955 elsif($_ =~ /^Features: (.*)/i) {
1957 if($feat =~ /TrackMemory/i) {
1958 # curl was built with --enable-curldebug (memory tracking)
1961 if($feat =~ /debug/i) {
1962 # curl was built with --enable-debug
1964 # set the NETRC debug env
1965 $ENV{'CURL_DEBUG_NETRC'} = "$LOGDIR/netrc";
1967 if($feat =~ /SSL/i) {
1971 if($feat =~ /Largefile/i) {
1972 # large file support
1975 if($feat =~ /IDN/i) {
1979 if($feat =~ /IPv6/i) {
1982 if($feat =~ /libz/i) {
1985 if($feat =~ /NTLM/i) {
1989 if($feat =~ /CharConv/i) {
1996 logmsg "unable to get curl's version, further details are:\n";
1997 logmsg "issued command: \n";
1998 logmsg "$versioncmd \n";
1999 if ($versretval == -1) {
2000 logmsg "command failed with: \n";
2001 logmsg "$versnoexec \n";
2003 elsif ($versretval & 127) {
2004 logmsg sprintf("command died with signal %d, and %s coredump.\n",
2005 ($versretval & 127), ($versretval & 128)?"a":"no");
2008 logmsg sprintf("command exited with value %d \n", $versretval >> 8);
2010 logmsg "contents of $curlverout: \n";
2011 displaylogcontent("$curlverout");
2012 logmsg "contents of $curlvererr: \n";
2013 displaylogcontent("$curlvererr");
2014 die "couldn't get curl's version";
2017 if(-r "../lib/curl_config.h") {
2018 open(CONF, "<../lib/curl_config.h");
2020 if($_ =~ /^\#define HAVE_GETRLIMIT/) {
2028 # client has ipv6 support
2030 # check if the HTTP server has it!
2031 my @sws = `server/sws --version`;
2032 if($sws[0] =~ /IPv6/) {
2033 # HTTP server has ipv6 support!
2037 # check if the FTP server has it!
2038 @sws = `server/sockfilt --version`;
2039 if($sws[0] =~ /IPv6/) {
2040 # FTP server has ipv6 support!
2045 if(!$curl_debug && $torture) {
2046 die "can't run torture tests since curl was not built with curldebug";
2049 $has_shared = `sh $CURLCONFIG --built-shared`;
2052 # curl doesn't list cryptographic support separately, so assume it's
2056 my $hostname=join(' ', runclientoutput("hostname"));
2057 my $hosttype=join(' ', runclientoutput("uname -a"));
2059 logmsg ("********* System characteristics ******** \n",
2062 "* Features: $feat\n",
2063 "* Host: $hostname",
2064 "* System: $hosttype");
2066 logmsg sprintf("* Server SSL: %8s", $stunnel?"ON ":"OFF");
2067 logmsg sprintf(" libcurl SSL: %s\n", $ssl_version?"ON ":"OFF");
2068 logmsg sprintf("* debug build: %8s", $debug_build?"ON ":"OFF");
2069 logmsg sprintf(" track memory: %s\n", $curl_debug?"ON ":"OFF");
2070 logmsg sprintf("* valgrind: %8s", $valgrind?"ON ":"OFF");
2071 logmsg sprintf(" HTTP IPv6 %s\n", $http_ipv6?"ON ":"OFF");
2072 logmsg sprintf("* FTP IPv6 %8s", $ftp_ipv6?"ON ":"OFF");
2073 logmsg sprintf(" Libtool lib: %s\n", $libtool?"ON ":"OFF");
2074 logmsg sprintf("* Shared build: %s\n", $has_shared);
2076 logmsg sprintf("* SSL library: %13s\n", $ssllib);
2079 logmsg "* Ports:\n";
2081 logmsg sprintf("* HTTP/%d ", $HTTPPORT);
2082 logmsg sprintf("FTP/%d ", $FTPPORT);
2083 logmsg sprintf("FTP2/%d ", $FTP2PORT);
2084 logmsg sprintf("RTSP/%d ", $RTSPPORT);
2086 logmsg sprintf("FTPS/%d ", $FTPSPORT);
2087 logmsg sprintf("HTTPS/%d ", $HTTPSPORT);
2089 logmsg sprintf("\n* TFTP/%d ", $TFTPPORT);
2091 logmsg sprintf("HTTP-IPv6/%d ", $HTTP6PORT);
2092 logmsg sprintf("RTSP-IPv6/%d ", $RTSP6PORT);
2095 logmsg sprintf("FTP-IPv6/%d ", $FTP6PORT);
2098 logmsg sprintf("TFTP-IPv6/%d ", $TFTP6PORT);
2100 logmsg sprintf("\n* SSH/%d ", $SSHPORT);
2101 logmsg sprintf("SOCKS/%d ", $SOCKSPORT);
2102 logmsg sprintf("POP3/%d ", $POP3PORT);
2103 logmsg sprintf("IMAP/%d ", $IMAPPORT);
2104 logmsg sprintf("SMTP/%d\n", $SMTPPORT);
2106 logmsg sprintf("* POP3-IPv6/%d ", $POP36PORT);
2107 logmsg sprintf("IMAP-IPv6/%d ", $IMAP6PORT);
2108 logmsg sprintf("SMTP-IPv6/%d\n", $SMTP6PORT);
2111 $has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys');
2113 logmsg "***************************************** \n";
2116 #######################################################################
2117 # substitute the variable stuff into either a joined up file or
2118 # a command, in either case passed by reference
2122 $$thing =~ s/%HOSTIP/$HOSTIP/g;
2123 $$thing =~ s/%HTTPPORT/$HTTPPORT/g;
2124 $$thing =~ s/%HOST6IP/$HOST6IP/g;
2125 $$thing =~ s/%HTTP6PORT/$HTTP6PORT/g;
2126 $$thing =~ s/%HTTPSPORT/$HTTPSPORT/g;
2127 $$thing =~ s/%FTPPORT/$FTPPORT/g;
2128 $$thing =~ s/%FTP6PORT/$FTP6PORT/g;
2129 $$thing =~ s/%FTP2PORT/$FTP2PORT/g;
2130 $$thing =~ s/%FTPSPORT/$FTPSPORT/g;
2131 $$thing =~ s/%SRCDIR/$srcdir/g;
2132 $$thing =~ s/%PWD/$pwd/g;
2133 $$thing =~ s/%TFTPPORT/$TFTPPORT/g;
2134 $$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
2135 $$thing =~ s/%SSHPORT/$SSHPORT/g;
2136 $$thing =~ s/%SOCKSPORT/$SOCKSPORT/g;
2137 $$thing =~ s/%POP3PORT/$POP3PORT/g;
2138 $$thing =~ s/%POP36PORT/$POP36PORT/g;
2139 $$thing =~ s/%IMAPPORT/$IMAPPORT/g;
2140 $$thing =~ s/%IMAP6PORT/$IMAP6PORT/g;
2141 $$thing =~ s/%SMTPPORT/$SMTPPORT/g;
2142 $$thing =~ s/%SMTP6PORT/$SMTP6PORT/g;
2143 $$thing =~ s/%CURL/$CURL/g;
2144 $$thing =~ s/%USER/$USER/g;
2145 $$thing =~ s/%CLIENTIP/$CLIENTIP/g;
2146 $$thing =~ s/%CLIENT6IP/$CLIENT6IP/g;
2147 $$thing =~ s/%RTSPPORT/$RTSPPORT/g;
2148 $$thing =~ s/%RTSP6PORT/$RTSP6PORT/g;
2150 # The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be
2151 # used for time-out tests and that whould work on most hosts as these
2152 # adjust for the startup/check time for this particular host. We needed
2153 # to do this to make the test suite run better on very slow hosts.
2155 my $ftp2 = $ftpchecktime * 2;
2156 my $ftp3 = $ftpchecktime * 3;
2158 $$thing =~ s/%FTPTIME2/$ftp2/g;
2159 $$thing =~ s/%FTPTIME3/$ftp3/g;
2171 #######################################################################
2172 # Provide time stamps for single test skipped events
2174 sub timestampskippedevents {
2175 my $testnum = $_[0];
2177 return if((not defined($testnum)) || ($testnum < 1));
2181 if($timevrfyend{$testnum}) {
2184 elsif($timesrvrlog{$testnum}) {
2185 $timevrfyend{$testnum} = $timesrvrlog{$testnum};
2188 elsif($timetoolend{$testnum}) {
2189 $timevrfyend{$testnum} = $timetoolend{$testnum};
2190 $timesrvrlog{$testnum} = $timetoolend{$testnum};
2192 elsif($timetoolini{$testnum}) {
2193 $timevrfyend{$testnum} = $timetoolini{$testnum};
2194 $timesrvrlog{$testnum} = $timetoolini{$testnum};
2195 $timetoolend{$testnum} = $timetoolini{$testnum};
2197 elsif($timesrvrend{$testnum}) {
2198 $timevrfyend{$testnum} = $timesrvrend{$testnum};
2199 $timesrvrlog{$testnum} = $timesrvrend{$testnum};
2200 $timetoolend{$testnum} = $timesrvrend{$testnum};
2201 $timetoolini{$testnum} = $timesrvrend{$testnum};
2203 elsif($timesrvrini{$testnum}) {
2204 $timevrfyend{$testnum} = $timesrvrini{$testnum};
2205 $timesrvrlog{$testnum} = $timesrvrini{$testnum};
2206 $timetoolend{$testnum} = $timesrvrini{$testnum};
2207 $timetoolini{$testnum} = $timesrvrini{$testnum};
2208 $timesrvrend{$testnum} = $timesrvrini{$testnum};
2210 elsif($timeprepini{$testnum}) {
2211 $timevrfyend{$testnum} = $timeprepini{$testnum};
2212 $timesrvrlog{$testnum} = $timeprepini{$testnum};
2213 $timetoolend{$testnum} = $timeprepini{$testnum};
2214 $timetoolini{$testnum} = $timeprepini{$testnum};
2215 $timesrvrend{$testnum} = $timeprepini{$testnum};
2216 $timesrvrini{$testnum} = $timeprepini{$testnum};
2221 #######################################################################
2222 # Run a single specified test case
2225 my ($testnum, $count, $total)=@_;
2232 # copy test number to a global scope var, this allows
2233 # testnum checking when starting test harness servers.
2234 $testnumcheck = $testnum;
2236 # timestamp test preparation start
2237 $timeprepini{$testnum} = Time::HiRes::time() if($timestats);
2239 if($disttests !~ /test$testnum\W/ ) {
2240 logmsg "Warning: test$testnum not present in tests/data/Makefile.am\n";
2243 # load the test case file definition
2244 if(loadtest("${TESTDIR}/test${testnum}")) {
2246 # this is not a test
2247 logmsg "RUN: $testnum doesn't look like a test case\n";
2252 @what = getpart("client", "features");
2259 $feature{$f}=$f; # we require this feature
2266 elsif($f eq "OpenSSL") {
2271 elsif($f eq "GnuTLS") {
2276 elsif($f eq "NSS") {
2281 elsif($f eq "netrc_debug") {
2286 elsif($f eq "large_file") {
2291 elsif($f eq "idn") {
2296 elsif($f eq "ipv6") {
2301 elsif($f eq "libz") {
2306 elsif($f eq "NTLM") {
2311 elsif($f eq "getrlimit") {
2312 if($has_getrlimit) {
2316 elsif($f eq "crypto") {
2321 elsif($f eq "socks") {
2324 # See if this "feature" is in the list of supported protocols
2325 elsif (grep /^$f$/, @protocols) {
2329 $why = "curl lacks $f support";
2334 my @keywords = getpart("info", "keywords");
2337 for $k (@keywords) {
2339 if ($disabled_keywords{$k}) {
2340 $why = "disabled by keyword";
2341 } elsif ($enabled_keywords{$k}) {
2346 if(!$why && !$match && %enabled_keywords) {
2347 $why = "disabled by missing keyword";
2351 # timestamp required servers verification start
2352 $timesrvrini{$testnum} = Time::HiRes::time() if($timestats);
2355 $why = serverfortest($testnum);
2358 # timestamp required servers verification end
2359 $timesrvrend{$testnum} = Time::HiRes::time() if($timestats);
2361 # test definition may instruct to (un)set environment vars
2362 # this is done this early, so that the precheck can use environment
2363 # variables and still bail out fine on errors
2365 my @setenv = getpart("client", "setenv");
2367 foreach my $s (@setenv) {
2370 if($s =~ /([^=]*)=(.*)/) {
2371 my ($var, $content) = ($1, $2);
2372 # remember current setting, to restore it once test runs
2373 $oldenv{$var} = ($ENV{$var})?"$ENV{$var}":'notset';
2376 delete $ENV{$var} if($ENV{$var});
2379 if(($var =~ /^LD_PRELOAD/) &&
2380 ($debug_build || ($has_shared ne "yes"))) {
2381 # print "Skipping LD_PRELOAD due to no release shared build\n";
2384 $ENV{$var} = "$content";
2392 # Add a precheck cache. If a precheck command was already invoked
2393 # exactly like this, then use the previous result to speed up
2394 # successive test invokes!
2396 my @precheck = getpart("client", "precheck");
2398 $cmd = $precheck[0];
2402 my @p = split(/ /, $cmd);
2404 # the first word, the command, does not contain a slash so
2405 # we will scan the "improved" PATH to find the command to
2407 my $fullp = checktestcmd($p[0]);
2412 $cmd = join(" ", @p);
2415 my @o = `$cmd 2>/dev/null`;
2420 $why = "precheck command error";
2422 logmsg "prechecked $cmd\n" if($verbose);
2427 if($why && !$listonly) {
2428 # there's a problem, count it as "skipped"
2431 $teststat[$testnum]=$why; # store reason for this test case
2434 printf "test %03d SKIPPED: $why\n", $testnum;
2437 timestampskippedevents($testnum);
2440 logmsg sprintf("test %03d...", $testnum);
2442 # extract the reply data
2443 my @reply = getpart("reply", "data");
2444 my @replycheck = getpart("reply", "datacheck");
2447 # we use this file instead to check the final output against
2449 my %hash = getpartattr("reply", "datacheck");
2450 if($hash{'nonewline'}) {
2451 # Yes, we must cut off the final newline from the final line
2453 chomp($replycheck[$#replycheck]);
2459 # curl command to run
2460 my @curlcmd= fixarray ( getpart("client", "command") );
2462 # this is the valid protocol blurb curl should generate
2463 my @protocol= fixarray ( getpart("verify", "protocol") );
2465 # redirected stdout/stderr to these files
2466 $STDOUT="$LOGDIR/stdout$testnum";
2467 $STDERR="$LOGDIR/stderr$testnum";
2469 # if this section exists, we verify that the stdout contained this:
2470 my @validstdout = fixarray ( getpart("verify", "stdout") );
2472 # if this section exists, we verify upload
2473 my @upload = getpart("verify", "upload");
2475 # if this section exists, it might be FTP server instructions:
2476 my @ftpservercmd = getpart("reply", "servercmd");
2478 my $CURLOUT="$LOGDIR/curl$testnum.out"; # curl output if not stdout
2481 my @testname= getpart("client", "name");
2484 my $name = $testname[0];
2490 timestampskippedevents($testnum);
2491 return 0; # look successful
2494 my @codepieces = getpart("client", "tool");
2498 $tool = $codepieces[0];
2502 # remove server output logfiles
2507 # write the instructions to file
2508 writearray($FTPDCMD, \@ftpservercmd);
2511 # get the command line options to use
2513 ($cmd, @blaha)= getpart("client", "command");
2515 # make some nice replace operations
2516 $cmd =~ s/\n//g; # no newlines please
2518 # substitute variables in the command line
2525 # create a (possibly-empty) file before starting the test
2526 my @inputfile=getpart("client", "file");
2527 my %fileattr = getpartattr("client", "file");
2528 my $filename=$fileattr{'name'};
2529 if(@inputfile || $filename) {
2531 logmsg "ERROR: section client=>file has no name attribute\n";
2532 timestampskippedevents($testnum);
2535 my $fileContent = join('', @inputfile);
2536 subVariables \$fileContent;
2537 # logmsg "DEBUG: writing file " . $filename . "\n";
2538 open(OUTFILE, ">$filename");
2539 binmode OUTFILE; # for crapage systems, use binary
2540 print OUTFILE $fileContent;
2544 my %cmdhash = getpartattr("client", "command");
2548 if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-output/)) {
2549 #We may slap on --output!
2550 if (!@validstdout) {
2551 $out=" --output $CURLOUT ";
2555 my $serverlogslocktimeout = $defserverlogslocktimeout;
2556 if($cmdhash{'timeout'}) {
2557 # test is allowed to override default server logs lock timeout
2558 if($cmdhash{'timeout'} =~ /(\d+)/) {
2559 $serverlogslocktimeout = $1 if($1 >= 0);
2563 my $postcommanddelay = $defpostcommanddelay;
2564 if($cmdhash{'delay'}) {
2565 # test is allowed to specify a delay after command is executed
2566 if($cmdhash{'delay'} =~ /(\d+)/) {
2567 $postcommanddelay = $1 if($1 > 0);
2573 # run curl, add --verbose for debug information output
2574 $cmdargs ="$out --include --verbose --trace-time $cmd";
2577 $cmdargs = " $cmd"; # $cmd is the command line for the test file
2578 $CURLOUT = $STDOUT; # sends received data to stdout
2581 my @stdintest = getpart("client", "stdin");
2584 my $stdinfile="$LOGDIR/stdin-for-$testnum";
2585 writearray($stdinfile, \@stdintest);
2587 $cmdargs .= " <$stdinfile";
2595 $CMDLINE="$LIBDIR/$tool";
2597 print "The tool set in the test case for this: '$tool' does not exist\n";
2598 timestampskippedevents($testnum);
2606 my @valgrindoption = getpart("verify", "valgrind");
2607 if((!@valgrindoption) || ($valgrindoption[0] !~ /disable/)) {
2609 my $valgrindcmd = "$valgrind ";
2610 $valgrindcmd .= "$valgrind_tool " if($valgrind_tool);
2611 $valgrindcmd .= "--leak-check=yes ";
2612 $valgrindcmd .= "--num-callers=16 ";
2613 $valgrindcmd .= "${valgrind_logfile}=$LOGDIR/valgrind$testnum";
2614 $CMDLINE = "$valgrindcmd $CMDLINE";
2618 $CMDLINE .= "$cmdargs >>$STDOUT 2>>$STDERR";
2621 logmsg "$CMDLINE\n";
2624 print CMDLOG "$CMDLINE\n";
2631 # Apr 2007: precommand isn't being used and could be removed
2632 my @precommand= getpart("client", "precommand");
2633 if($precommand[0]) {
2634 # this is pure perl to eval!
2635 my $code = join("", @precommand);
2638 logmsg "perl: $code\n";
2639 logmsg "precommand: $@";
2640 stopservers($verbose);
2641 timestampskippedevents($testnum);
2647 my $gdbinit = "$TESTDIR/gdbinit$testnum";
2648 open(GDBCMD, ">$LOGDIR/gdbcmd");
2649 print GDBCMD "set args $cmdargs\n";
2650 print GDBCMD "show args\n";
2651 print GDBCMD "source $gdbinit\n" if -e $gdbinit;
2655 # timestamp starting of test command
2656 $timetoolini{$testnum} = Time::HiRes::time() if($timestats);
2658 # run the command line we built
2660 $cmdres = torture($CMDLINE,
2661 "$gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
2664 runclient("$gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
2665 $cmdres=0; # makes it always continue after a debugged run
2668 $cmdres = runclient("$CMDLINE");
2669 my $signal_num = $cmdres & 127;
2670 $dumped_core = $cmdres & 128;
2672 if(!$anyway && ($signal_num || $dumped_core)) {
2677 $cmdres = (2000 + $signal_num) if($signal_num && !$cmdres);
2681 # timestamp finishing of test command
2682 $timetoolend{$testnum} = Time::HiRes::time() if($timestats);
2686 # there's core file present now!
2692 logmsg "core dumped\n";
2694 logmsg "running gdb for post-mortem analysis:\n";
2695 open(GDBCMD, ">$LOGDIR/gdbcmd2");
2696 print GDBCMD "bt\n";
2698 runclient("$gdb --directory libtest -x $LOGDIR/gdbcmd2 -batch $DBGCURL core ");
2699 # unlink("$LOGDIR/gdbcmd2");
2703 # If a server logs advisor read lock file exists, it is an indication
2704 # that the server has not yet finished writing out all its log files,
2705 # including server request log files used for protocol verification.
2706 # So, if the lock file exists the script waits here a certain amount
2707 # of time until the server removes it, or the given time expires.
2709 if($serverlogslocktimeout) {
2710 my $lockretry = $serverlogslocktimeout * 20;
2711 while((-f $SERVERLOGS_LOCK) && $lockretry--) {
2712 select(undef, undef, undef, 0.05);
2714 if(($lockretry < 0) &&
2715 ($serverlogslocktimeout >= $defserverlogslocktimeout)) {
2716 logmsg "Warning: server logs lock timeout ",
2717 "($serverlogslocktimeout seconds) expired\n";
2721 # Test harness ssh server does not have this synchronization mechanism,
2722 # this implies that some ssh server based tests might need a small delay
2723 # once that the client command has run to avoid false test failures.
2725 sleep($postcommanddelay) if($postcommanddelay);
2727 # timestamp removal of server logs advisor read lock
2728 $timesrvrlog{$testnum} = Time::HiRes::time() if($timestats);
2730 # test definition might instruct to stop some servers
2731 # stop also all servers relative to the given one
2733 my @killtestservers = getpart("client", "killserver");
2734 if(@killtestservers) {
2736 # All servers relative to the given one must be stopped also
2739 foreach my $server (@killtestservers) {
2741 if($server =~ /^(ftp|http|imap|pop3|smtp)s(.*)$/) {
2742 # given an ssl server, also kill non-ssl underlying one
2743 push @killservers, "${1}${2}";
2745 elsif($server =~ /^(ftp|http|imap|pop3|smtp)(.*)$/) {
2746 # given a non-ssl server, also kill ssl piggybacking one
2747 push @killservers, "${1}s${2}";
2749 elsif($server =~ /^(socks)(.*)$/) {
2750 # given an socks server, also kill ssh underlying one
2751 push @killservers, "ssh${2}";
2753 elsif($server =~ /^(ssh)(.*)$/) {
2754 # given an ssh server, also kill socks piggybacking one
2755 push @killservers, "socks${2}";
2757 push @killservers, $server;
2760 # kill sockfilter processes for pingpong relative servers
2762 foreach my $server (@killservers) {
2763 if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
2765 my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
2766 my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
2767 killsockfilters($proto, $ipvnum, $idnum, $verbose);
2771 # kill server relative pids clearing them in %run hash
2774 foreach my $server (@killservers) {
2776 $pidlist .= "$run{$server} ";
2779 $runcert{$server} = 0 if($runcert{$server});
2781 killpid($verbose, $pidlist);
2783 # cleanup server pid files
2785 foreach my $server (@killservers) {
2786 my $pidfile = $serverpidfile{$server};
2787 my $pid = processexists($pidfile);
2789 logmsg "Warning: $server server unexpectedly alive\n";
2790 killpid($verbose, $pid);
2792 unlink($pidfile) if(-f $pidfile);
2796 # remove the test server commands file after each test
2799 # run the postcheck command
2800 my @postcheck= getpart("client", "postcheck");
2802 $cmd = $postcheck[0];
2806 logmsg "postcheck $cmd\n" if($verbose);
2807 my $rc = runclient("$cmd");
2808 # Must run the postcheck command in torture mode in order
2809 # to clean up, but the result can't be relied upon.
2810 if($rc != 0 && !$torture) {
2811 logmsg " postcheck FAILED\n";
2812 # timestamp test result verification end
2813 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2819 # restore environment variables that were modified
2821 foreach my $var (keys %oldenv) {
2822 if($oldenv{$var} eq 'notset') {
2823 delete $ENV{$var} if($ENV{$var});
2826 $ENV{$var} = "$oldenv{$var}";
2831 # Skip all the verification on torture tests
2833 if(!$cmdres && !$keepoutfiles) {
2836 # timestamp test result verification end
2837 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2841 my @err = getpart("verify", "errorcode");
2842 my $errorcode = $err[0] || "0";
2846 # verify redirected stdout
2847 my @actual = loadarray($STDOUT);
2849 # variable-replace in the stdout we have from the test case file
2850 @validstdout = fixarray(@validstdout);
2852 # get all attributes
2853 my %hash = getpartattr("verify", "stdout");
2855 # get the mode attribute
2856 my $filemode=$hash{'mode'};
2857 if($filemode && ($filemode eq "text") && $has_textaware) {
2858 # text mode when running on windows: fix line endings
2859 map s/\r\n/\n/g, @actual;
2862 if($hash{'nonewline'}) {
2863 # Yes, we must cut off the final newline from the final line
2864 # of the protocol data
2865 chomp($validstdout[$#validstdout]);
2868 $res = compare("stdout", \@actual, \@validstdout);
2870 # timestamp test result verification end
2871 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2877 $ok .= "-"; # stdout not checked
2880 my %replyattr = getpartattr("reply", "data");
2881 if(!$replyattr{'nocheck'} && (@reply || $replyattr{'sendzero'})) {
2882 # verify the received data
2883 my @out = loadarray($CURLOUT);
2884 my %hash = getpartattr("reply", "data");
2885 # get the mode attribute
2886 my $filemode=$hash{'mode'};
2887 if($filemode && ($filemode eq "text") && $has_textaware) {
2888 # text mode when running on windows: fix line endings
2889 map s/\r\n/\n/g, @out;
2892 $res = compare("data", \@out, \@reply);
2894 # timestamp test result verification end
2895 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2901 $ok .= "-"; # data not checked
2905 # verify uploaded data
2906 my @out = loadarray("$LOGDIR/upload.$testnum");
2907 $res = compare("upload", \@out, \@upload);
2909 # timestamp test result verification end
2910 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2916 $ok .= "-"; # upload not checked
2920 # Verify the sent request
2921 my @out = loadarray($SERVERIN);
2923 # what to cut off from the live protocol sent by curl
2924 my @strip = getpart("verify", "strip");
2926 my @protstrip=@protocol;
2928 # check if there's any attributes on the verify/protocol section
2929 my %hash = getpartattr("verify", "protocol");
2931 if($hash{'nonewline'}) {
2932 # Yes, we must cut off the final newline from the final line
2933 # of the protocol data
2934 chomp($protstrip[$#protstrip]);
2938 # strip off all lines that match the patterns from both arrays
2940 @out = striparray( $_, \@out);
2941 @protstrip= striparray( $_, \@protstrip);
2944 # what parts to cut off from the protocol
2945 my @strippart = getpart("verify", "strippart");
2947 for $strip (@strippart) {
2954 $res = compare("protocol", \@out, \@protstrip);
2956 # timestamp test result verification end
2957 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2965 $ok .= "-"; # protocol not checked
2968 my @outfile=getpart("verify", "file");
2970 # we're supposed to verify a dynamically generated file!
2971 my %hash = getpartattr("verify", "file");
2973 my $filename=$hash{'name'};
2975 logmsg "ERROR: section verify=>file has no name attribute\n";
2976 stopservers($verbose);
2977 # timestamp test result verification end
2978 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2981 my @generated=loadarray($filename);
2983 # what parts to cut off from the file
2984 my @stripfile = getpart("verify", "stripfile");
2986 my $filemode=$hash{'mode'};
2987 if($filemode && ($filemode eq "text") && $has_textaware) {
2988 # text mode when running on windows means adding an extra
2990 push @stripfile, "s/\r\n/\n/";
2994 for $strip (@stripfile) {
3001 @outfile = fixarray(@outfile);
3003 $res = compare("output", \@generated, \@outfile);
3005 # timestamp test result verification end
3006 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3013 $ok .= "-"; # output not checked
3016 # accept multiple comma-separated error codes
3017 my @splerr = split(/ *, */, $errorcode);
3019 foreach my $e (@splerr) {
3032 printf("\n%s returned $cmdres, %d was expected\n",
3033 (!$tool)?"curl":$tool, $errorcode);
3035 logmsg " exit FAILED\n";
3036 # timestamp test result verification end
3037 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3043 logmsg "\n** ALERT! memory debugging with no output file?\n";
3046 my @memdata=`$memanalyze $memdump`;
3050 # well it could be other memory problems as well, but
3051 # we call it leak for short here
3056 logmsg "\n** MEMORY FAILURE\n";
3058 # timestamp test result verification end
3059 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3068 $ok .= "-"; # memory not checked
3073 unless(opendir(DIR, "$LOGDIR")) {
3074 logmsg "ERROR: unable to read $LOGDIR\n";
3075 # timestamp test result verification end
3076 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3079 my @files = readdir(DIR);
3082 foreach my $file (@files) {
3083 if($file =~ /^valgrind$testnum(\..*|)$/) {
3089 logmsg "ERROR: valgrind log file missing for test $testnum\n";
3090 # timestamp test result verification end
3091 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3094 my @e = valgrindparse($srcdir, $feature{'SSL'}, "$LOGDIR/$vgfile");
3096 logmsg " valgrind ERROR ";
3098 # timestamp test result verification end
3099 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3106 logmsg " valgrind SKIPPED\n";
3108 $ok .= "-"; # skipped
3112 $ok .= "-"; # valgrind not checked
3115 logmsg "$ok " if(!$short);
3117 my $sofar= time()-$start;
3118 my $esttotal = $sofar/$count * $total;
3119 my $estleft = $esttotal - $sofar;
3120 my $left=sprintf("remaining: %02d:%02d",
3123 printf "OK (%-3d out of %-3d, %s)\n", $count, $total, $left;
3125 # the test succeeded, remove all log files
3126 if(!$keepoutfiles) {
3130 # timestamp test result verification end
3131 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3136 #######################################################################
3137 # Stop all running test servers
3139 my $verbose = $_[0];
3141 # kill sockfilter processes for all pingpong servers
3143 killallsockfilters($verbose);
3145 # kill all server pids from %run hash clearing them
3148 foreach my $server (keys %run) {
3152 my $pids = $run{$server};
3153 foreach my $pid (split(' ', $pids)) {
3155 logmsg sprintf("* kill pid for %s => %d\n",
3161 $pidlist .= "$run{$server} ";
3164 $runcert{$server} = 0 if($runcert{$server});
3166 killpid($verbose, $pidlist);
3168 # cleanup all server pid files
3170 foreach my $server (keys %serverpidfile) {
3171 my $pidfile = $serverpidfile{$server};
3172 my $pid = processexists($pidfile);
3174 logmsg "Warning: $server server unexpectedly alive\n";
3175 killpid($verbose, $pid);
3177 unlink($pidfile) if(-f $pidfile);
3181 #######################################################################
3182 # startservers() starts all the named servers
3184 # Returns: string with error reason or blank for success
3190 my (@whatlist) = split(/\s+/,$_);
3191 my $what = lc($whatlist[0]);
3192 $what =~ s/[^a-z0-9-]//g;
3195 if($what =~ /^(ftp|http|imap|pop3|smtp)s(.*)$/) {
3196 $certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem';
3199 if(($what eq "pop3") ||
3201 ($what eq "imap") ||
3202 ($what eq "smtp")) {
3204 ($pid, $pid2) = runpingpongserver($what, "", $verbose);
3206 return "failed starting ". uc($what) ." server";
3208 printf ("* pid $what => %d %d\n", $pid, $pid2) if($verbose);
3209 $run{$what}="$pid $pid2";
3212 elsif($what eq "ftp2") {
3214 ($pid, $pid2) = runpingpongserver("ftp", "2", $verbose);
3216 return "failed starting FTP2 server";
3218 printf ("* pid ftp2 => %d %d\n", $pid, $pid2) if($verbose);
3219 $run{'ftp2'}="$pid $pid2";
3222 elsif($what eq "ftp-ipv6") {
3223 if(!$run{'ftp-ipv6'}) {
3224 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose, "ipv6");
3226 return "failed starting FTP-IPv6 server";
3228 logmsg sprintf("* pid ftp-ipv6 => %d %d\n", $pid,
3229 $pid2) if($verbose);
3230 $run{'ftp-ipv6'}="$pid $pid2";
3233 elsif($what eq "http") {
3235 ($pid, $pid2) = runhttpserver($verbose);
3237 return "failed starting HTTP server";
3239 printf ("* pid http => %d %d\n", $pid, $pid2) if($verbose);
3240 $run{'http'}="$pid $pid2";
3243 elsif($what eq "http-ipv6") {
3244 if(!$run{'http-ipv6'}) {
3245 ($pid, $pid2) = runhttpserver($verbose, "IPv6");
3247 return "failed starting HTTP-IPv6 server";
3249 logmsg sprintf("* pid http-ipv6 => %d %d\n", $pid, $pid2)
3251 $run{'http-ipv6'}="$pid $pid2";
3254 elsif($what eq "rtsp") {
3256 ($pid, $pid2) = runrtspserver($verbose);
3258 return "failed starting RTSP server";
3260 printf ("* pid rtsp => %d %d\n", $pid, $pid2) if($verbose);
3261 $run{'rtsp'}="$pid $pid2";
3264 elsif($what eq "rtsp-ipv6") {
3265 if(!$run{'rtsp-ipv6'}) {
3266 ($pid, $pid2) = runrtspserver($verbose, "IPv6");
3268 return "failed starting RTSP-IPv6 server";
3270 logmsg sprintf("* pid rtsp-ipv6 => %d %d\n", $pid, $pid2)
3272 $run{'rtsp-ipv6'}="$pid $pid2";
3276 elsif($what eq "ftps") {
3278 # we can't run ftps tests without stunnel
3279 return "no stunnel";
3282 # we can't run ftps tests if libcurl is SSL-less
3283 return "curl lacks SSL support";
3285 if($runcert{'ftps'} && ($runcert{'ftps'} ne $certfile)) {
3286 # stop server when running and using a different cert
3290 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose);
3292 return "failed starting FTP server";
3294 printf ("* pid ftp => %d %d\n", $pid, $pid2) if($verbose);
3295 $run{'ftp'}="$pid $pid2";
3298 ($pid, $pid2) = runftpsserver($verbose, "", $certfile);
3300 return "failed starting FTPS server (stunnel)";
3302 logmsg sprintf("* pid ftps => %d %d\n", $pid, $pid2)
3304 $run{'ftps'}="$pid $pid2";
3307 elsif($what eq "file") {
3308 # we support it but have no server!
3310 elsif($what eq "https") {
3312 # we can't run ftps tests without stunnel
3313 return "no stunnel";
3316 # we can't run ftps tests if libcurl is SSL-less
3317 return "curl lacks SSL support";
3319 if($runcert{'https'} && ($runcert{'https'} ne $certfile)) {
3320 # stop server when running and using a different cert
3321 stopserver('https');
3324 ($pid, $pid2) = runhttpserver($verbose);
3326 return "failed starting HTTP server";
3328 printf ("* pid http => %d %d\n", $pid, $pid2) if($verbose);
3329 $run{'http'}="$pid $pid2";
3331 if(!$run{'https'}) {
3332 ($pid, $pid2) = runhttpsserver($verbose, "", $certfile);
3334 return "failed starting HTTPS server (stunnel)";
3336 logmsg sprintf("* pid https => %d %d\n", $pid, $pid2)
3338 $run{'https'}="$pid $pid2";
3341 elsif($what eq "tftp") {
3343 ($pid, $pid2) = runtftpserver("", $verbose);
3345 return "failed starting TFTP server";
3347 printf ("* pid tftp => %d %d\n", $pid, $pid2) if($verbose);
3348 $run{'tftp'}="$pid $pid2";
3351 elsif($what eq "tftp-ipv6") {
3352 if(!$run{'tftp-ipv6'}) {
3353 ($pid, $pid2) = runtftpserver("", $verbose, "IPv6");
3355 return "failed starting TFTP-IPv6 server";
3357 printf("* pid tftp-ipv6 => %d %d\n", $pid, $pid2) if($verbose);
3358 $run{'tftp-ipv6'}="$pid $pid2";
3361 elsif($what eq "sftp" || $what eq "scp" || $what eq "socks4" || $what eq "socks5" ) {
3363 ($pid, $pid2) = runsshserver("", $verbose);
3365 return "failed starting SSH server";
3367 printf ("* pid ssh => %d %d\n", $pid, $pid2) if($verbose);
3368 $run{'ssh'}="$pid $pid2";
3370 if($what eq "socks4" || $what eq "socks5") {
3371 if(!$run{'socks'}) {
3372 ($pid, $pid2) = runsocksserver("", $verbose);
3374 return "failed starting socks server";
3376 printf ("* pid socks => %d %d\n", $pid, $pid2) if($verbose);
3377 $run{'socks'}="$pid $pid2";
3380 if($what eq "socks5") {
3382 # Not an OpenSSH or SunSSH ssh daemon
3383 logmsg "Not OpenSSH or SunSSH; socks5 tests need at least OpenSSH 3.7\n";
3384 return "failed starting socks5 server";
3386 elsif(($sshdid =~ /OpenSSH/) && ($sshdvernum < 370)) {
3387 # Need OpenSSH 3.7 for socks5 - http://www.openssh.com/txt/release-3.7
3388 logmsg "$sshdverstr insufficient; socks5 tests need at least OpenSSH 3.7\n";
3389 return "failed starting socks5 server";
3391 elsif(($sshdid =~ /SunSSH/) && ($sshdvernum < 100)) {
3392 # Need SunSSH 1.0 for socks5
3393 logmsg "$sshdverstr insufficient; socks5 tests need at least SunSSH 1.0\n";
3394 return "failed starting socks5 server";
3398 elsif($what eq "none") {
3399 logmsg "* starts no server\n" if ($verbose);
3402 warn "we don't support a server for $what";
3403 return "no server for $what";
3409 ##############################################################################
3410 # This function makes sure the right set of server is running for the
3411 # specified test case. This is a useful design when we run single tests as not
3412 # all servers need to run then!
3414 # Returns: a string, blank if everything is fine or a reason why it failed
3420 my @what = getpart("client", "server");
3423 warn "Test case $testnum has no server(s) specified";
3424 return "no server specified";
3430 $proto =~ s/\s.*//g; # take first word
3431 if (! grep /^$proto$/, @protocols) {
3432 if (substr($proto,0,5) ne "socks") {
3433 return "curl lacks $proto support";
3438 return &startservers(@what);
3441 #######################################################################
3442 # runtimestats displays test-suite run time statistics
3445 my $lasttest = $_[0];
3447 return if(not $timestats);
3449 logmsg "\nTest suite total running time breakdown per task...\n\n";
3457 my $timesrvrtot = 0.0;
3458 my $timepreptot = 0.0;
3459 my $timetooltot = 0.0;
3460 my $timelocktot = 0.0;
3461 my $timevrfytot = 0.0;
3462 my $timetesttot = 0.0;
3465 for my $testnum (1 .. $lasttest) {
3466 if($timesrvrini{$testnum}) {
3467 $timesrvrtot += $timesrvrend{$testnum} - $timesrvrini{$testnum};
3469 (($timetoolini{$testnum} - $timeprepini{$testnum}) -
3470 ($timesrvrend{$testnum} - $timesrvrini{$testnum}));
3471 $timetooltot += $timetoolend{$testnum} - $timetoolini{$testnum};
3472 $timelocktot += $timesrvrlog{$testnum} - $timetoolend{$testnum};
3473 $timevrfytot += $timevrfyend{$testnum} - $timesrvrlog{$testnum};
3474 $timetesttot += $timevrfyend{$testnum} - $timeprepini{$testnum};
3475 push @timesrvr, sprintf("%06.3f %04d",
3476 $timesrvrend{$testnum} - $timesrvrini{$testnum}, $testnum);
3477 push @timeprep, sprintf("%06.3f %04d",
3478 ($timetoolini{$testnum} - $timeprepini{$testnum}) -
3479 ($timesrvrend{$testnum} - $timesrvrini{$testnum}), $testnum);
3480 push @timetool, sprintf("%06.3f %04d",
3481 $timetoolend{$testnum} - $timetoolini{$testnum}, $testnum);
3482 push @timelock, sprintf("%06.3f %04d",
3483 $timesrvrlog{$testnum} - $timetoolend{$testnum}, $testnum);
3484 push @timevrfy, sprintf("%06.3f %04d",
3485 $timevrfyend{$testnum} - $timesrvrlog{$testnum}, $testnum);
3486 push @timetest, sprintf("%06.3f %04d",
3487 $timevrfyend{$testnum} - $timeprepini{$testnum}, $testnum);
3492 no warnings 'numeric';
3493 @timesrvr = sort { $b <=> $a } @timesrvr;
3494 @timeprep = sort { $b <=> $a } @timeprep;
3495 @timetool = sort { $b <=> $a } @timetool;
3496 @timelock = sort { $b <=> $a } @timelock;
3497 @timevrfy = sort { $b <=> $a } @timevrfy;
3498 @timetest = sort { $b <=> $a } @timetest;
3501 logmsg "Spent ". sprintf("%08.3f ", $timesrvrtot) .
3502 "seconds starting and verifying test harness servers.\n";
3503 logmsg "Spent ". sprintf("%08.3f ", $timepreptot) .
3504 "seconds reading definitions and doing test preparations.\n";
3505 logmsg "Spent ". sprintf("%08.3f ", $timetooltot) .
3506 "seconds actually running test tools.\n";
3507 logmsg "Spent ". sprintf("%08.3f ", $timelocktot) .
3508 "seconds awaiting server logs lock removal.\n";
3509 logmsg "Spent ". sprintf("%08.3f ", $timevrfytot) .
3510 "seconds verifying test results.\n";
3511 logmsg "Spent ". sprintf("%08.3f ", $timetesttot) .
3512 "seconds doing all of the above.\n";
3515 logmsg "\nTest server starting and verification time per test ".
3516 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3517 logmsg "-time- test\n";
3518 logmsg "------ ----\n";
3519 foreach my $txt (@timesrvr) {
3520 last if((not $fullstats) && (not $counter--));
3525 logmsg "\nTest definition reading and preparation time per test ".
3526 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3527 logmsg "-time- test\n";
3528 logmsg "------ ----\n";
3529 foreach my $txt (@timeprep) {
3530 last if((not $fullstats) && (not $counter--));
3535 logmsg "\nTest tool execution time per test ".
3536 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3537 logmsg "-time- test\n";
3538 logmsg "------ ----\n";
3539 foreach my $txt (@timetool) {
3540 last if((not $fullstats) && (not $counter--));
3545 logmsg "\nTest server logs lock removal time per test ".
3546 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3547 logmsg "-time- test\n";
3548 logmsg "------ ----\n";
3549 foreach my $txt (@timelock) {
3550 last if((not $fullstats) && (not $counter--));
3555 logmsg "\nTest results verification time per test ".
3556 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3557 logmsg "-time- test\n";
3558 logmsg "------ ----\n";
3559 foreach my $txt (@timevrfy) {
3560 last if((not $fullstats) && (not $counter--));
3565 logmsg "\nTotal time per test ".
3566 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
3567 logmsg "-time- test\n";
3568 logmsg "------ ----\n";
3569 foreach my $txt (@timetest) {
3570 last if((not $fullstats) && (not $counter--));
3577 #######################################################################
3578 # Check options to this test program
3586 if ($ARGV[0] eq "-v") {
3590 elsif($ARGV[0] =~ /^-b(.*)/) {
3592 if($portno =~ s/(\d+)$//) {
3596 elsif ($ARGV[0] eq "-c") {
3597 # use this path to curl instead of default
3598 $DBGCURL=$CURL=$ARGV[1];
3601 elsif ($ARGV[0] eq "-d") {
3602 # have the servers display protocol output
3605 elsif ($ARGV[0] eq "-f") {
3606 # run fork-servers, which makes the server fork for all new
3607 # connections This is NOT what you wanna do without knowing exactly
3611 elsif ($ARGV[0] eq "-g") {
3612 # run this test with gdb
3615 elsif($ARGV[0] eq "-s") {
3619 elsif($ARGV[0] eq "-n") {
3623 elsif($ARGV[0] =~ /^-t(.*)/) {
3628 if($xtra =~ s/(\d+)$//) {
3631 # we undef valgrind to make this fly in comparison
3634 elsif($ARGV[0] eq "-a") {
3635 # continue anyway, even if a test fail
3638 elsif($ARGV[0] eq "-p") {
3641 elsif($ARGV[0] eq "-l") {
3642 # lists the test case names only
3645 elsif($ARGV[0] eq "-k") {
3646 # keep stdout and stderr files after tests
3649 elsif($ARGV[0] eq "-r") {
3650 # run time statistics needs Time::HiRes
3651 if($Time::HiRes::VERSION) {
3652 keys(%timeprepini) = 1000;
3653 keys(%timesrvrini) = 1000;
3654 keys(%timesrvrend) = 1000;
3655 keys(%timetoolini) = 1000;
3656 keys(%timetoolend) = 1000;
3657 keys(%timesrvrlog) = 1000;
3658 keys(%timevrfyend) = 1000;
3663 elsif($ARGV[0] eq "-rf") {
3664 # run time statistics needs Time::HiRes
3665 if($Time::HiRes::VERSION) {
3666 keys(%timeprepini) = 1000;
3667 keys(%timesrvrini) = 1000;
3668 keys(%timesrvrend) = 1000;
3669 keys(%timetoolini) = 1000;
3670 keys(%timetoolend) = 1000;
3671 keys(%timesrvrlog) = 1000;
3672 keys(%timevrfyend) = 1000;
3677 elsif(($ARGV[0] eq "-h") || ($ARGV[0] eq "--help")) {
3680 Usage: runtests.pl [options] [test selection(s)]
3681 -a continue even if a test fails
3682 -bN use base port number N for test servers (default $base)
3683 -c path use this curl executable
3684 -d display server debug info
3685 -g run the test case with gdb
3687 -k keep stdout and stderr files present after tests
3688 -l list all test case names/descriptions
3690 -p print log file contents when a test fails
3691 -r run time statistics
3692 -rf full run time statistics
3694 -t[N] torture (simulate memory alloc failures); N means fail Nth alloc
3696 [num] like "5 6 9" or " 5 to 22 " to run those tests only
3697 [!num] like "!5 !6 !9" to disable those tests
3698 [keyword] like "IPv6" to select only tests containing the key word
3699 [!keyword] like "!cookies" to disable any tests containing the key word
3704 elsif($ARGV[0] =~ /^(\d+)/) {
3707 for($fromnum .. $number) {
3716 elsif($ARGV[0] =~ /^to$/i) {
3717 $fromnum = $number+1;
3719 elsif($ARGV[0] =~ /^!(\d+)/) {
3723 elsif($ARGV[0] =~ /^!(.+)/) {
3724 $disabled_keywords{$1}=$1;
3726 elsif($ARGV[0] =~ /^([-[{a-zA-Z].*)/) {
3727 $enabled_keywords{$1}=$1;
3730 print "Unknown option: $ARGV[0]\n";
3736 if(@testthis && ($testthis[0] ne "")) {
3737 $TESTCASES=join(" ", @testthis);
3741 # we have found valgrind on the host, use it
3743 # verify that we can invoke it fine
3744 my $code = runclient("valgrind >/dev/null 2>&1");
3746 if(($code>>8) != 1) {
3747 #logmsg "Valgrind failure, disable it\n";
3751 # since valgrind 2.1.x, '--tool' option is mandatory
3752 # use it, if it is supported by the version installed on the system
3753 runclient("valgrind --help 2>&1 | grep -- --tool > /dev/null 2>&1");
3755 $valgrind_tool="--tool=memcheck";
3760 # A shell script. This is typically when built with libtool,
3761 $valgrind="../libtool --mode=execute $valgrind";
3765 # valgrind 3 renamed the --logfile option to --log-file!!!
3766 my $ver=join(' ', runclientoutput("valgrind --version"));
3767 # cut off all but digits and dots
3768 $ver =~ s/[^0-9.]//g;
3770 if($ver =~ /^(\d+)/) {
3773 $valgrind_logfile="--log-file";
3780 # open the executable curl and read the first 4 bytes of it
3781 open(CHECK, "<$CURL");
3783 sysread CHECK, $c, 4;
3786 # A shell script. This is typically when built with libtool,
3788 $gdb = "libtool --mode=execute gdb";
3792 $HTTPPORT = $base++; # HTTP server port
3793 $HTTPSPORT = $base++; # HTTPS server port
3794 $FTPPORT = $base++; # FTP server port
3795 $FTPSPORT = $base++; # FTPS server port
3796 $HTTP6PORT = $base++; # HTTP IPv6 server port (different IP protocol
3797 # but we follow the same port scheme anyway)
3798 $FTP2PORT = $base++; # FTP server 2 port
3799 $FTP6PORT = $base++; # FTP IPv6 port
3800 $TFTPPORT = $base++; # TFTP (UDP) port
3801 $TFTP6PORT = $base++; # TFTP IPv6 (UDP) port
3802 $SSHPORT = $base++; # SSH (SCP/SFTP) port
3803 $SOCKSPORT = $base++; # SOCKS port
3804 $POP3PORT = $base++;
3805 $POP36PORT = $base++;
3806 $IMAPPORT = $base++;
3807 $IMAP6PORT = $base++;
3808 $SMTPPORT = $base++;
3809 $SMTP6PORT = $base++;
3810 $RTSPPORT = $base++;
3811 $RTSP6PORT = $base++;
3813 #######################################################################
3814 # clear and create logging directory:
3818 mkdir($LOGDIR, 0777);
3820 #######################################################################
3821 # initialize some variables
3825 init_serverpidfile_hash();
3827 #######################################################################
3828 # Output curl version and host info being tested
3835 #######################################################################
3836 # If 'all' tests are requested, find out all test numbers
3839 if ( $TESTCASES eq "all") {
3840 # Get all commands and find out their test numbers
3841 opendir(DIR, $TESTDIR) || die "can't opendir $TESTDIR: $!";
3842 my @cmds = grep { /^test([0-9]+)$/ && -f "$TESTDIR/$_" } readdir(DIR);
3845 open(D, "<$TESTDIR/DISABLED");
3852 $disabled{$1}=$1; # disable this test number
3857 $TESTCASES=""; # start with no test cases
3859 # cut off everything but the digits
3861 $_ =~ s/[a-z\/\.]*//g;
3863 # sort the numbers from low to high
3864 foreach my $n (sort { $a <=> $b } @cmds) {
3866 # skip disabled test cases
3867 my $why = "configured as DISABLED";
3870 $teststat[$n]=$why; # store reason for this test case
3873 $TESTCASES .= " $n";
3877 #######################################################################
3878 # Start the command line log
3880 open(CMDLOG, ">$CURLLOG") ||
3881 logmsg "can't log command lines to $CURLLOG\n";
3883 #######################################################################
3885 # Display the contents of the given file. Line endings are canonicalized
3886 # and excessively long files are elided
3887 sub displaylogcontent {
3889 if(open(SINGLE, "<$file")) {
3893 while(my $string = <SINGLE>) {
3894 $string =~ s/\r\n/\n/g;
3895 $string =~ s/[\r\f\032]/\n/g;
3896 $string .= "\n" unless ($string =~ /\n$/);
3898 for my $line (split("\n", $string)) {
3899 $line =~ s/\s*\!$//;
3901 push @tail, " $line\n";
3906 $truncate = $linecount > 1000;
3912 my $tailtotal = scalar @tail;
3913 if($tailtotal > $tailshow) {
3914 $tailskip = $tailtotal - $tailshow;
3915 logmsg "=== File too long: $tailskip lines omitted here\n";
3917 for($tailskip .. $tailtotal-1) {
3927 opendir(DIR, "$LOGDIR") ||
3928 die "can't open dir: $!";
3929 my @logs = readdir(DIR);
3932 logmsg "== Contents of files in the $LOGDIR/ dir after test $testnum\n";
3933 foreach my $log (sort @logs) {
3934 if($log =~ /\.(\.|)$/) {
3935 next; # skip "." and ".."
3937 if($log =~ /^\.nfs/) {
3940 if(($log eq "memdump") || ($log eq "core")) {
3941 next; # skip "memdump" and "core"
3943 if((-d "$LOGDIR/$log") || (! -s "$LOGDIR/$log")) {
3944 next; # skip directory and empty files
3946 if(($log =~ /^stdout\d+/) && ($log !~ /^stdout$testnum/)) {
3947 next; # skip stdoutNnn of other tests
3949 if(($log =~ /^stderr\d+/) && ($log !~ /^stderr$testnum/)) {
3950 next; # skip stderrNnn of other tests
3952 if(($log =~ /^upload\d+/) && ($log !~ /^upload$testnum/)) {
3953 next; # skip uploadNnn of other tests
3955 if(($log =~ /^curl\d+\.out/) && ($log !~ /^curl$testnum\.out/)) {
3956 next; # skip curlNnn.out of other tests
3958 if(($log =~ /^test\d+\.txt/) && ($log !~ /^test$testnum\.txt/)) {
3959 next; # skip testNnn.txt of other tests
3961 if(($log =~ /^file\d+\.txt/) && ($log !~ /^file$testnum\.txt/)) {
3962 next; # skip fileNnn.txt of other tests
3964 if(($log =~ /^valgrind\d+/) && ($log !~ /^valgrind$testnum(\..*|)$/)) {
3965 next; # skip valgrindNnn of other tests
3967 logmsg "=== Start of file $log\n";
3968 displaylogcontent("$LOGDIR/$log");
3969 logmsg "=== End of file $log\n";
3973 #######################################################################
3974 # The main test-loop
3982 my @at = split(" ", $TESTCASES);
3987 foreach $testnum (@at) {
3989 $lasttest = $testnum if($testnum > $lasttest);
3992 my $error = singletest($testnum, $count, scalar(@at));
3994 # not a test we can run
3998 $total++; # number of tests we've run
4001 $failed.= "$testnum ";
4003 # display all files in log/ in a nice way
4004 displaylogs($testnum);
4007 # a test failed, abort
4008 logmsg "\n - abort tests\n";
4013 $ok++; # successful test counter
4016 # loop for next test
4019 my $sofar = time() - $start;
4021 #######################################################################
4026 # Tests done, stop the servers
4027 stopservers($verbose);
4029 my $all = $total + $skipped;
4031 runtimestats($lasttest);
4034 logmsg sprintf("TESTDONE: $ok tests out of $total reported OK: %d%%\n",
4038 logmsg "TESTFAIL: These test cases failed: $failed\n";
4042 logmsg "TESTFAIL: No tests were performed\n";
4046 logmsg "TESTDONE: $all tests were considered during ".
4047 sprintf("%.0f", $sofar) ." seconds.\n";
4052 logmsg "TESTINFO: $skipped tests were skipped due to these restraints:\n";
4054 for(keys %skipped) {
4056 printf "TESTINFO: \"%s\" %d times (", $r, $skipped{$_};
4058 # now show all test case numbers that had this reason for being
4061 for(0 .. scalar @teststat) {
4063 if($teststat[$_] && ($teststat[$_] eq $r)) {
4073 if($total && ($ok != $total)) {