2 #***************************************************************************
4 # Project ___| | | | _ \| |
6 # | (__| |_| | _ <| |___
7 # \___|\___/|_| \_\_____|
9 # Copyright (C) 1998 - 2015, 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 push(@INC, $ENV{'srcdir'}) if(defined $ENV{'srcdir'});
61 # run time statistics needs Time::HiRes
65 import Time::HiRes qw( time );
73 # Subs imported from serverhelp module
83 # Variables and subs imported from sshhelp module
108 require "getpart.pm"; # array functions
109 require "valgrind.pm"; # valgrind report parser
112 my $HOSTIP="127.0.0.1"; # address on which the test server listens
113 my $HOST6IP="[::1]"; # address on which the test server listens
114 my $CLIENTIP="127.0.0.1"; # address which curl uses for incoming connections
115 my $CLIENT6IP="[::1]"; # address which curl uses for incoming connections
117 my $base = 8990; # base port number
119 my $HTTPPORT; # HTTP server port
120 my $HTTP6PORT; # HTTP IPv6 server port
121 my $HTTPSPORT; # HTTPS (stunnel) server port
122 my $FTPPORT; # FTP server port
123 my $FTP2PORT; # FTP server 2 port
124 my $FTPSPORT; # FTPS (stunnel) server port
125 my $FTP6PORT; # FTP IPv6 server port
127 my $TFTP6PORT; # TFTP
128 my $SSHPORT; # SCP/SFTP
129 my $SOCKSPORT; # SOCKS4/5 port
131 my $POP36PORT; # POP3 IPv6 server port
133 my $IMAP6PORT; # IMAP IPv6 server port
135 my $SMTP6PORT; # SMTP IPv6 server port
137 my $RTSP6PORT; # RTSP IPv6 server port
138 my $GOPHERPORT; # Gopher
139 my $GOPHER6PORT; # Gopher IPv6 server port
140 my $HTTPTLSPORT; # HTTP TLS (non-stunnel) server port
141 my $HTTPTLS6PORT; # HTTP TLS (non-stunnel) IPv6 server port
142 my $HTTPPROXYPORT; # HTTP proxy port, when using CONNECT
143 my $HTTPPIPEPORT; # HTTP pipelining port
144 my $HTTPUNIXPATH; # HTTP server Unix domain socket path
146 my $srcdir = $ENV{'srcdir'} || '.';
147 my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
148 my $VCURL=$CURL; # what curl binary to use to verify the servers with
149 # VCURL is handy to set to the system one when the one you
150 # just built hangs or crashes and thus prevent verification
151 my $DBGCURL=$CURL; #"../src/.libs/curl"; # alternative for debugging
153 my $TESTDIR="$srcdir/data";
154 my $LIBDIR="./libtest";
155 my $UNITDIR="./unit";
156 # TODO: change this to use server_inputfilename()
157 my $SERVERIN="$LOGDIR/server.input"; # what curl sent the server
158 my $SERVER2IN="$LOGDIR/server2.input"; # what curl sent the second server
159 my $PROXYIN="$LOGDIR/proxy.input"; # what curl sent the proxy
160 my $CURLLOG="$LOGDIR/curl.log"; # all command lines run
161 my $FTPDCMD="$LOGDIR/ftpserver.cmd"; # copy ftp server instructions here
162 my $SERVERLOGS_LOCK="$LOGDIR/serverlogs.lock"; # server logs advisor read lock
163 my $CURLCONFIG="../curl-config"; # curl-config from current build
165 # Normally, all test cases should be run, but at times it is handy to
166 # simply run a particular one:
169 # To run specific test cases, set them like:
170 # $TESTCASES="1 2 3 7 8";
172 #######################################################################
173 # No variables below this point should need to be modified
176 # invoke perl like this:
177 my $perl="perl -I$srcdir";
178 my $server_response_maxtime=13;
180 my $debug_build=0; # built debug enabled (--enable-debug)
181 my $has_memory_tracking=0; # built with memory tracking (--enable-curldebug)
184 # name of the file that the memory debugging creates:
185 my $memdump="$LOGDIR/memdump";
187 # the path to the script that analyzes the memory debug output file:
188 my $memanalyze="$perl $srcdir/memanalyze.pl";
190 my $pwd = getcwd(); # current working directory
193 my $ftpchecktime=1; # time it took to verify our test FTP server
195 my $stunnel = checkcmd("stunnel4") || checkcmd("tstunnel") || checkcmd("stunnel");
196 my $valgrind = checktestcmd("valgrind");
197 my $valgrind_logfile="--logfile";
199 my $gdb = checktestcmd("gdb");
200 my $httptlssrv = find_httptlssrv();
202 my $ssl_version; # set if libcurl is built with SSL support
203 my $large_file; # set if libcurl is built with large file support
204 my $has_idn; # set if libcurl is built with IDN support
205 my $http_ipv6; # set if HTTP server has IPv6 support
206 my $http_unix; # set if HTTP server has Unix sockets support
207 my $ftp_ipv6; # set if FTP server has IPv6 support
208 my $tftp_ipv6; # set if TFTP server has IPv6 support
209 my $gopher_ipv6; # set if Gopher server has IPv6 support
210 my $has_ipv6; # set if libcurl is built with IPv6 support
211 my $has_unix; # set if libcurl is built with Unix sockets support
212 my $has_libz; # set if libcurl is built with libz support
213 my $has_getrlimit; # set if system has getrlimit()
214 my $has_ntlm; # set if libcurl is built with NTLM support
215 my $has_ntlm_wb; # set if libcurl is built with NTLM delegation to winbind
216 my $has_sspi; # set if libcurl is built with Windows SSPI
217 my $has_gssapi; # set if libcurl is built with a GSS-API library
218 my $has_kerberos; # set if libcurl is built with Kerberos support
219 my $has_spnego; # set if libcurl is built with SPNEGO support
220 my $has_charconv; # set if libcurl is built with CharConv support
221 my $has_tls_srp; # set if libcurl is built with TLS-SRP support
222 my $has_metalink; # set if curl is built with Metalink support
223 my $has_http2; # set if libcurl is built with HTTP2 support
224 my $has_crypto; # set if libcurl is built with cryptographic support
225 my $has_cares; # set if built with c-ares
226 my $has_threadedres;# set if built with threaded resolver
228 # this version is decided by the particular nghttp2 library that is being used
231 my $has_openssl; # built with a lib using an OpenSSL-like API
232 my $has_gnutls; # built with GnuTLS
233 my $has_nss; # built with NSS
234 my $has_yassl; # built with yassl
235 my $has_polarssl; # built with polarssl
236 my $has_axtls; # built with axTLS
237 my $has_winssl; # built with WinSSL (Secure Channel aka Schannel)
238 my $has_darwinssl; # built with DarwinSSL (Secure Transport)
239 my $has_boringssl; # built with BoringSSL
240 my $has_libressl; # built with libressl
242 my $has_sslpinning; # built with a TLS backend that supports pinning
244 my $has_shared = "unknown"; # built shared
246 my $resolver; # name of the resolver backend (for human presentation)
247 my $ssllib; # name of the SSL library we use (for human presentation)
249 my $has_textaware; # set if running on a system that has a text mode concept
250 # on files. Windows for example
252 my @protocols; # array of lowercase supported protocol servers
254 my $skipped=0; # number of tests skipped; reported in main loop
255 my %skipped; # skipped{reason}=counter, reasons for skip
256 my @teststat; # teststat[testnum]=reason, reasons for skip
257 my %disabled_keywords; # key words of tests to skip
258 my %enabled_keywords; # key words of tests to run
259 my %disabled; # disabled test cases
261 my $sshdid; # for socks server, ssh daemon version id
262 my $sshdvernum; # for socks server, ssh daemon version number
263 my $sshdverstr; # for socks server, ssh daemon version string
264 my $sshderror; # for socks server, ssh daemon version error
266 my $defserverlogslocktimeout = 20; # timeout to await server logs lock removal
267 my $defpostcommanddelay = 0; # delay between command and postcheck sections
269 my $timestats; # time stamping and stats generation
270 my $fullstats; # show time stats for every single test
271 my %timeprepini; # timestamp for each test preparation start
272 my %timesrvrini; # timestamp for each test required servers verification start
273 my %timesrvrend; # timestamp for each test required servers verification end
274 my %timetoolini; # timestamp for each test command run starting
275 my %timetoolend; # timestamp for each test command run stopping
276 my %timesrvrlog; # timestamp for each test server logs lock removal
277 my %timevrfyend; # timestamp for each test result verification end
279 my $testnumcheck; # test number, set in singletest sub.
282 #######################################################################
283 # variables that command line options may set
291 my $gdbthis; # run test case with gdb debugger
292 my $gdbxwin; # use windowed gdb when using gdb
293 my $keepoutfiles; # keep stdout and stderr files after tests
294 my $listonly; # only list the tests
295 my $postmortem; # display detailed info about failed tests
296 my $run_event_based; # run curl with --test-event to test the event API
298 my %run; # running server
299 my %doesntrun; # servers that don't work, identified by pidfile
300 my %serverpidfile;# all server pid file names, identified by server id
301 my %runcert; # cert file currently in use by an ssl running server
303 # torture test variables
308 #######################################################################
309 # logmsg is our general message logging subroutine.
317 # get the name of the current user
318 my $USER = $ENV{USER}; # Linux
320 $USER = $ENV{USERNAME}; # Windows
322 $USER = $ENV{LOGNAME}; # Some Unix (I think)
326 # enable memory debugging if curl is compiled with it
327 $ENV{'CURL_MEMDEBUG'} = $memdump;
328 $ENV{'CURL_ENTROPY'}="12345678";
329 $ENV{'CURL_FORCETIME'}=1; # for debug NTLM magic
334 logmsg "runtests.pl received SIG$signame, exiting\n";
335 stopservers($verbose);
336 die "Somebody sent me a SIG$signame";
338 $SIG{INT} = \&catch_zap;
339 $SIG{TERM} = \&catch_zap;
341 ##########################################################################
342 # Clear all possible '*_proxy' environment variables for various protocols
343 # to prevent them to interfere with our testing!
346 foreach $protocol (('ftp', 'http', 'ftps', 'https', 'no', 'all')) {
347 my $proxy = "${protocol}_proxy";
348 # clear lowercase version
349 delete $ENV{$proxy} if($ENV{$proxy});
350 # clear uppercase version
351 delete $ENV{uc($proxy)} if($ENV{uc($proxy)});
354 # make sure we don't get affected by other variables that control our
357 delete $ENV{'SSL_CERT_DIR'} if($ENV{'SSL_CERT_DIR'});
358 delete $ENV{'SSL_CERT_PATH'} if($ENV{'SSL_CERT_PATH'});
359 delete $ENV{'CURL_CA_BUNDLE'} if($ENV{'CURL_CA_BUNDLE'});
361 #######################################################################
362 # Load serverpidfile hash with pidfile names for all possible servers.
364 sub init_serverpidfile_hash {
365 for my $proto (('ftp', 'http', 'imap', 'pop3', 'smtp')) {
366 for my $ssl (('', 's')) {
367 for my $ipvnum ((4, 6)) {
368 for my $idnum ((1, 2, 3)) {
369 my $serv = servername_id("$proto$ssl", $ipvnum, $idnum);
370 my $pidf = server_pidfilename("$proto$ssl", $ipvnum, $idnum);
371 $serverpidfile{$serv} = $pidf;
376 for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp', 'gopher', 'httptls')) {
377 for my $ipvnum ((4, 6)) {
378 for my $idnum ((1, 2)) {
379 my $serv = servername_id($proto, $ipvnum, $idnum);
380 my $pidf = server_pidfilename($proto, $ipvnum, $idnum);
381 $serverpidfile{$serv} = $pidf;
385 for my $proto (('http', 'imap', 'pop3', 'smtp')) {
386 for my $ssl (('', 's')) {
387 my $serv = servername_id("$proto$ssl", "unix", 1);
388 my $pidf = server_pidfilename("$proto$ssl", "unix", 1);
389 $serverpidfile{$serv} = $pidf;
394 #######################################################################
395 # Check if a given child process has just died. Reaps it if so.
398 use POSIX ":sys_wait_h";
400 if(not defined $pid || $pid <= 0) {
403 my $rc = waitpid($pid, &WNOHANG);
404 return ($rc == $pid)?1:0;
407 #######################################################################
408 # Start a new thread/process and run the given command line in there.
409 # Return the pids (yes plural) of the new child process to the parent.
412 my ($cmd, $pidfile, $timeout, $fake)=@_;
414 logmsg "startnew: $cmd\n" if ($verbose);
419 if(not defined $child) {
420 logmsg "startnew: fork() failure detected\n";
425 # Here we are the child. Run the given command.
427 # Put an "exec" in front of the command so that the child process
428 # keeps this child's process ID.
429 exec("exec $cmd") || die "Can't exec() $cmd: $!";
431 # exec() should never return back here to this process. We protect
432 # ourselves by calling die() just in case something goes really bad.
433 die "error: exec() has returned";
436 # Ugly hack but ssh client and gnutls-serv don't support pid files
438 if(open(OUT, ">$pidfile")) {
439 print OUT $child . "\n";
441 logmsg "startnew: $pidfile faked with pid=$child\n" if($verbose);
444 logmsg "startnew: failed to write fake $pidfile with pid=$child\n";
446 # could/should do a while connect fails sleep a bit and loop
448 if (checkdied($child)) {
449 logmsg "startnew: child process has failed to start\n" if($verbose);
454 my $count = $timeout;
456 if(-f $pidfile && -s $pidfile && open(PID, "<$pidfile")) {
459 if(($pid2 > 0) && pidexists($pid2)) {
460 # if $pid2 is valid, then make sure this pid is alive, as
461 # otherwise it is just likely to be the _previous_ pidfile or
465 # invalidate $pid2 if not actually alive
468 if (checkdied($child)) {
469 logmsg "startnew: child process has died, server might start up\n"
471 # We can't just abort waiting for the server with a
473 # because the server might have forked and could still start
474 # up normally. Instead, just reduce the amount of time we remain
481 # Return two PIDs, the one for the child process we spawned and the one
482 # reported by the server itself (in case it forked again on its own).
483 # Both (potentially) need to be killed at the end of the test.
484 return ($child, $pid2);
488 #######################################################################
489 # Check for a command in the PATH of the test server.
493 my @paths=(split(":", $ENV{'PATH'}), "/usr/sbin", "/usr/local/sbin",
494 "/sbin", "/usr/bin", "/usr/local/bin",
495 "./libtest/.libs", "./libtest");
497 if( -x "$_/$cmd" && ! -d "$_/$cmd") {
498 # executable bit but not a directory!
504 #######################################################################
505 # Get the list of tests that the tests/data/Makefile.am knows about!
509 my @dist = `cd data && make show`;
510 $disttests = join("", @dist);
513 #######################################################################
514 # Check for a command in the PATH of the machine running curl.
518 return checkcmd($cmd);
521 #######################################################################
522 # Run the application under test and return its return code
526 my $ret = system($cmd);
527 print "CMD ($ret): $cmd\n" if($verbose && !$torture);
530 # This is one way to test curl on a remote machine
531 # my $out = system("ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'");
532 # sleep 2; # time to allow the NFS server to be updated
536 #######################################################################
537 # Run the application under test and return its stdout
539 sub runclientoutput {
543 # This is one way to test curl on a remote machine
544 # my @out = `ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'`;
545 # sleep 2; # time to allow the NFS server to be updated
549 #######################################################################
550 # Memory allocation test and failure torture testing.
556 # remove memdump first to be sure we get a new nice and clean one
559 # First get URL from test server, ignore the output/result
562 logmsg " CMD: $testcmd\n" if($verbose);
564 # memanalyze -v is our friend, get the number of allocations made
566 my @out = `$memanalyze -v $memdump`;
568 if(/^Allocations: (\d+)/) {
574 logmsg " found no allocs to make fail\n";
578 logmsg " $count allocations to make fail\n";
580 for ( 1 .. $count ) {
585 if($tortalloc && ($tortalloc != $limit)) {
590 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
592 my $now = sprintf("%02d:%02d:%02d ", $hour, $min, $sec);
593 logmsg "Fail alloc no: $limit at $now\r";
596 # make the memory allocation function number $limit return failure
597 $ENV{'CURL_MEMLIMIT'} = $limit;
599 # remove memdump first to be sure we get a new nice and clean one
602 logmsg "*** Alloc number $limit is now set to fail ***\n" if($gdbthis);
609 $ret = runclient($testcmd);
611 #logmsg "$_ Returned " . ($ret >> 8) . "\n";
613 # Now clear the variable again
614 delete $ENV{'CURL_MEMLIMIT'} if($ENV{'CURL_MEMLIMIT'});
617 # there's core file present now!
618 logmsg " core dumped\n";
623 # verify that it returns a proper error code, doesn't leak memory
624 # and doesn't core dump
625 if(($ret & 255) || ($ret >> 8) >= 128) {
626 logmsg " system() returned $ret\n";
630 my @memdata=`$memanalyze $memdump`;
634 # well it could be other memory problems as well, but
635 # we call it leak for short here
640 logmsg "** MEMORY FAILURE\n";
642 logmsg `$memanalyze -l $memdump`;
647 logmsg " Failed on alloc number $limit in test.\n",
648 " invoke with \"-t$limit\" to repeat this single case.\n";
649 stopservers($verbose);
654 logmsg "torture OK\n";
658 #######################################################################
659 # Stop a test server along with pids which aren't in the %run hash yet.
660 # This also stops all servers which are relative to the given one.
663 my ($server, $pidlist) = @_;
665 # kill sockfilter processes for pingpong relative server
667 if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
669 my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
670 my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
671 killsockfilters($proto, $ipvnum, $idnum, $verbose);
674 # All servers relative to the given one must be stopped also
677 if($server =~ /^(ftp|http|imap|pop3|smtp|httppipe)s((\d*)(-ipv6|-unix|))$/) {
678 # given a stunnel based ssl server, also kill non-ssl underlying one
679 push @killservers, "${1}${2}";
681 elsif($server =~ /^(ftp|http|imap|pop3|smtp|httppipe)((\d*)(-ipv6|-unix|))$/) {
682 # given a non-ssl server, also kill stunnel based ssl piggybacking one
683 push @killservers, "${1}s${2}";
685 elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
686 # given a socks server, also kill ssh underlying one
687 push @killservers, "ssh${2}";
689 elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
690 # given a ssh server, also kill socks piggybacking one
691 push @killservers, "socks${2}";
693 push @killservers, $server;
695 # kill given pids and server relative ones clearing them in %run hash
697 foreach my $server (@killservers) {
699 # we must prepend a space since $pidlist may already contain a pid
700 $pidlist .= " $run{$server}";
703 $runcert{$server} = 0 if($runcert{$server});
705 killpid($verbose, $pidlist);
707 # cleanup server pid files
709 foreach my $server (@killservers) {
710 my $pidfile = $serverpidfile{$server};
711 my $pid = processexists($pidfile);
713 logmsg "Warning: $server server unexpectedly alive\n";
714 killpid($verbose, $pid);
716 unlink($pidfile) if(-f $pidfile);
720 #######################################################################
721 # Verify that the server that runs on $ip, $port is our server. This also
722 # implies that we can speak with it, as there might be occasions when the
723 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
724 # assign requested address")
727 my ($proto, $ipvnum, $idnum, $ip, $port_or_path) = @_;
728 my $server = servername_id($proto, $ipvnum, $idnum);
731 # $port_or_path contains a path for Unix sockets, sws ignores the port
732 my $port = ($ipvnum eq "unix") ? 80 : $port_or_path;
734 my $verifyout = "$LOGDIR/".
735 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
736 unlink($verifyout) if(-f $verifyout);
738 my $verifylog = "$LOGDIR/".
739 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
740 unlink($verifylog) if(-f $verifylog);
742 if($proto eq "gopher") {
747 my $flags = "--max-time $server_response_maxtime ";
748 $flags .= "--output $verifyout ";
749 $flags .= "--silent ";
750 $flags .= "--verbose ";
751 $flags .= "--globoff ";
752 $flags .= "--unix-socket '$port_or_path' " if $ipvnum eq "unix";
753 $flags .= "-1 " if($has_axtls);
754 $flags .= "--insecure " if($proto eq 'https');
755 $flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\"";
757 my $cmd = "$VCURL $flags 2>$verifylog";
759 # verify if our/any server is running on this port
760 logmsg "RUN: $cmd\n" if($verbose);
761 my $res = runclient($cmd);
763 $res >>= 8; # rotate the result
765 logmsg "RUN: curl command died with a coredump\n";
769 if($res && $verbose) {
770 logmsg "RUN: curl command returned $res\n";
771 if(open(FILE, "<$verifylog")) {
772 while(my $string = <FILE>) {
773 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
780 if(open(FILE, "<$verifyout")) {
781 while(my $string = <FILE>) {
783 last; # only want first line
788 if($data && ($data =~ /WE ROOLZ: (\d+)/)) {
792 # curl: (6) Couldn't resolve host '::1'
793 logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
796 elsif($data || ($res && ($res != 7))) {
797 logmsg "RUN: Unknown server on our $server port: $port ($res)\n";
803 #######################################################################
804 # Verify that the server that runs on $ip, $port is our server. This also
805 # implies that we can speak with it, as there might be occasions when the
806 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
807 # assign requested address")
810 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
811 my $server = servername_id($proto, $ipvnum, $idnum);
816 my $verifylog = "$LOGDIR/".
817 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
818 unlink($verifylog) if(-f $verifylog);
820 if($proto eq "ftps") {
821 $extra .= "--insecure --ftp-ssl-control ";
824 my $flags = "--max-time $server_response_maxtime ";
825 $flags .= "--silent ";
826 $flags .= "--verbose ";
827 $flags .= "--globoff ";
829 $flags .= "\"$proto://$ip:$port/verifiedserver\"";
831 my $cmd = "$VCURL $flags 2>$verifylog";
833 # check if this is our server running on this port:
834 logmsg "RUN: $cmd\n" if($verbose);
835 my @data = runclientoutput($cmd);
837 my $res = $? >> 8; # rotate the result
839 logmsg "RUN: curl command died with a coredump\n";
843 foreach my $line (@data) {
844 if($line =~ /WE ROOLZ: (\d+)/) {
845 # this is our test server with a known pid!
850 if($pid <= 0 && @data && $data[0]) {
851 # this is not a known server
852 logmsg "RUN: Unknown server on our $server port: $port\n";
855 # we can/should use the time it took to verify the FTP server as a measure
856 # on how fast/slow this host/FTP is.
857 my $took = int(0.5+time()-$time);
860 logmsg "RUN: Verifying our test $server server took $took seconds\n";
862 $ftpchecktime = $took>=1?$took:1; # make sure it never is below 1
867 #######################################################################
868 # Verify that the server that runs on $ip, $port is our server. This also
869 # implies that we can speak with it, as there might be occasions when the
870 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
871 # assign requested address")
874 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
875 my $server = servername_id($proto, $ipvnum, $idnum);
878 my $verifyout = "$LOGDIR/".
879 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
880 unlink($verifyout) if(-f $verifyout);
882 my $verifylog = "$LOGDIR/".
883 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
884 unlink($verifylog) if(-f $verifylog);
886 my $flags = "--max-time $server_response_maxtime ";
887 $flags .= "--output $verifyout ";
888 $flags .= "--silent ";
889 $flags .= "--verbose ";
890 $flags .= "--globoff ";
891 # currently verification is done using http
892 $flags .= "\"http://$ip:$port/verifiedserver\"";
894 my $cmd = "$VCURL $flags 2>$verifylog";
896 # verify if our/any server is running on this port
897 logmsg "RUN: $cmd\n" if($verbose);
898 my $res = runclient($cmd);
900 $res >>= 8; # rotate the result
902 logmsg "RUN: curl command died with a coredump\n";
906 if($res && $verbose) {
907 logmsg "RUN: curl command returned $res\n";
908 if(open(FILE, "<$verifylog")) {
909 while(my $string = <FILE>) {
910 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
917 if(open(FILE, "<$verifyout")) {
918 while(my $string = <FILE>) {
920 last; # only want first line
925 if($data && ($data =~ /RTSP_SERVER WE ROOLZ: (\d+)/)) {
929 # curl: (6) Couldn't resolve host '::1'
930 logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
933 elsif($data || ($res != 7)) {
934 logmsg "RUN: Unknown server on our $server port: $port\n";
940 #######################################################################
941 # Verify that the ssh server has written out its pidfile, recovering
942 # the pid from the file and returning it if a process with that pid is
946 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
947 my $server = servername_id($proto, $ipvnum, $idnum);
948 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
950 if(open(FILE, "<$pidfile")) {
955 # if we have a pid it is actually our ssh server,
956 # since runsshserver() unlinks previous pidfile
957 if(!pidexists($pid)) {
958 logmsg "RUN: SSH server has died after starting up\n";
967 #######################################################################
968 # Verify that we can connect to the sftp server, properly authenticate
969 # with generated config and key files and run a simple remote pwd.
972 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
973 my $server = servername_id($proto, $ipvnum, $idnum);
975 # Find out sftp client canonical file name
976 my $sftp = find_sftp();
978 logmsg "RUN: SFTP server cannot find $sftpexe\n";
981 # Find out ssh client canonical file name
982 my $ssh = find_ssh();
984 logmsg "RUN: SFTP server cannot find $sshexe\n";
987 # Connect to sftp server, authenticate and run a remote pwd
988 # command using our generated configuration and key files
989 my $cmd = "\"$sftp\" -b $sftpcmds -F $sftpconfig -S \"$ssh\" $ip > $sftplog 2>&1";
990 my $res = runclient($cmd);
991 # Search for pwd command response in log file
992 if(open(SFTPLOGFILE, "<$sftplog")) {
993 while(<SFTPLOGFILE>) {
994 if(/^Remote working directory: /) {
1004 #######################################################################
1005 # Verify that the non-stunnel HTTP TLS extensions capable server that runs
1006 # on $ip, $port is our server. This also implies that we can speak with it,
1007 # as there might be occasions when the server runs fine but we cannot talk
1008 # to it ("Failed to connect to ::1: Can't assign requested address")
1011 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1012 my $server = servername_id($proto, $ipvnum, $idnum);
1013 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
1016 my $verifyout = "$LOGDIR/".
1017 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
1018 unlink($verifyout) if(-f $verifyout);
1020 my $verifylog = "$LOGDIR/".
1021 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
1022 unlink($verifylog) if(-f $verifylog);
1024 my $flags = "--max-time $server_response_maxtime ";
1025 $flags .= "--output $verifyout ";
1026 $flags .= "--verbose ";
1027 $flags .= "--globoff ";
1028 $flags .= "--insecure ";
1029 $flags .= "--tlsauthtype SRP ";
1030 $flags .= "--tlsuser jsmith ";
1031 $flags .= "--tlspassword abc ";
1032 $flags .= "\"https://$ip:$port/verifiedserver\"";
1034 my $cmd = "$VCURL $flags 2>$verifylog";
1036 # verify if our/any server is running on this port
1037 logmsg "RUN: $cmd\n" if($verbose);
1038 my $res = runclient($cmd);
1040 $res >>= 8; # rotate the result
1042 logmsg "RUN: curl command died with a coredump\n";
1046 if($res && $verbose) {
1047 logmsg "RUN: curl command returned $res\n";
1048 if(open(FILE, "<$verifylog")) {
1049 while(my $string = <FILE>) {
1050 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
1057 if(open(FILE, "<$verifyout")) {
1058 while(my $string = <FILE>) {
1064 if($data && ($data =~ /(GNUTLS|GnuTLS)/) && open(FILE, "<$pidfile")) {
1068 # if we have a pid it is actually our httptls server,
1069 # since runhttptlsserver() unlinks previous pidfile
1070 if(!pidexists($pid)) {
1071 logmsg "RUN: $server server has died after starting up\n";
1080 # curl: (6) Couldn't resolve host '::1'
1081 logmsg "RUN: failed to resolve host (https://$ip:$port/verifiedserver)\n";
1084 elsif($data || ($res && ($res != 7))) {
1085 logmsg "RUN: Unknown server on our $server port: $port ($res)\n";
1091 #######################################################################
1092 # STUB for verifying socks
1095 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1096 my $server = servername_id($proto, $ipvnum, $idnum);
1097 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
1099 if(open(FILE, "<$pidfile")) {
1104 # if we have a pid it is actually our socks server,
1105 # since runsocksserver() unlinks previous pidfile
1106 if(!pidexists($pid)) {
1107 logmsg "RUN: SOCKS server has died after starting up\n";
1116 #######################################################################
1117 # Verify that the server that runs on $ip, $port is our server.
1118 # Retry over several seconds before giving up. The ssh server in
1119 # particular can take a long time to start if it needs to generate
1120 # keys on a slow or loaded host.
1122 # Just for convenience, test harness uses 'https' and 'httptls' literals
1123 # as values for 'proto' variable in order to differentiate different
1124 # servers. 'https' literal is used for stunnel based https test servers,
1125 # and 'httptls' is used for non-stunnel https test servers.
1128 my %protofunc = ('http' => \&verifyhttp,
1129 'https' => \&verifyhttp,
1130 'rtsp' => \&verifyrtsp,
1131 'ftp' => \&verifyftp,
1132 'pop3' => \&verifyftp,
1133 'imap' => \&verifyftp,
1134 'smtp' => \&verifyftp,
1135 'httppipe' => \&verifyhttp,
1136 'ftps' => \&verifyftp,
1137 'tftp' => \&verifyftp,
1138 'ssh' => \&verifyssh,
1139 'socks' => \&verifysocks,
1140 'gopher' => \&verifyhttp,
1141 'httptls' => \&verifyhttptls);
1144 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1146 my $count = 30; # try for this many seconds
1150 my $fun = $protofunc{$proto};
1152 $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port);
1158 # a real failure, stop trying and bail out
1166 #######################################################################
1167 # Single shot server responsiveness test. This should only be used
1168 # to verify that a server present in %run hash is still functional
1170 sub responsiveserver {
1171 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1172 my $prev_verbose = $verbose;
1175 my $fun = $protofunc{$proto};
1176 my $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port);
1177 $verbose = $prev_verbose;
1180 return 1; # responsive
1183 my $srvrname = servername_str($proto, $ipvnum, $idnum);
1184 logmsg " server precheck FAILED (unresponsive $srvrname server)\n";
1188 #######################################################################
1189 # start the http server
1192 my ($proto, $verbose, $alt, $port_or_path) = @_;
1201 my $exe = "$perl $srcdir/httpserver.pl";
1202 my $verbose_flag = "--verbose ";
1204 if($alt eq "ipv6") {
1205 # if IPv6, use a different setup
1209 elsif($alt eq "proxy") {
1210 # basically the same, but another ID
1213 elsif($alt eq "pipe") {
1214 # basically the same, but another ID
1216 $exe = "python $srcdir/http_pipe.py";
1217 $verbose_flag .= "1 ";
1219 elsif($alt eq "unix") {
1220 # IP (protocol) is mutually exclusive with Unix sockets
1224 $server = servername_id($proto, $ipvnum, $idnum);
1226 $pidfile = $serverpidfile{$server};
1228 # don't retry if the server doesn't work
1229 if ($doesntrun{$pidfile}) {
1233 my $pid = processexists($pidfile);
1235 stopserver($server, "$pid");
1237 unlink($pidfile) if(-f $pidfile);
1239 $srvrname = servername_str($proto, $ipvnum, $idnum);
1241 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1243 $flags .= "--gopher " if($proto eq "gopher");
1244 $flags .= "--connect $HOSTIP " if($alt eq "proxy");
1245 $flags .= $verbose_flag if($debugprotocol);
1246 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1247 $flags .= "--id $idnum " if($idnum > 1);
1248 if($ipvnum eq "unix") {
1249 $flags .= "--unix-socket '$port_or_path' ";
1251 $flags .= "--ipv$ipvnum --port $port_or_path ";
1253 $flags .= "--srcdir \"$srcdir\"";
1255 my $cmd = "$exe $flags";
1256 my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1258 if($httppid <= 0 || !pidexists($httppid)) {
1260 logmsg "RUN: failed to start the $srvrname server\n";
1261 stopserver($server, "$pid2");
1262 displaylogs($testnumcheck);
1263 $doesntrun{$pidfile} = 1;
1267 # Server is up. Verify that we can speak to it.
1268 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
1270 logmsg "RUN: $srvrname server failed verification\n";
1271 # failed to talk to it properly. Kill the server and return failure
1272 stopserver($server, "$httppid $pid2");
1273 displaylogs($testnumcheck);
1274 $doesntrun{$pidfile} = 1;
1280 logmsg "RUN: $srvrname server is now running PID $httppid\n";
1285 return ($httppid, $pid2);
1288 #######################################################################
1289 # start the http server
1291 sub runhttp_pipeserver {
1292 my ($proto, $verbose, $alt, $port) = @_;
1302 if($alt eq "ipv6") {
1306 $server = servername_id($proto, $ipvnum, $idnum);
1308 $pidfile = $serverpidfile{$server};
1310 # don't retry if the server doesn't work
1311 if ($doesntrun{$pidfile}) {
1315 my $pid = processexists($pidfile);
1317 stopserver($server, "$pid");
1319 unlink($pidfile) if(-f $pidfile);
1321 $srvrname = servername_str($proto, $ipvnum, $idnum);
1323 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1325 $flags .= "--verbose 1 " if($debugprotocol);
1326 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1327 $flags .= "--id $idnum " if($idnum > 1);
1328 $flags .= "--port $port --srcdir \"$srcdir\"";
1330 my $cmd = "$srcdir/http_pipe.py $flags";
1331 my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1333 if($httppid <= 0 || !pidexists($httppid)) {
1335 logmsg "RUN: failed to start the $srvrname server\n";
1336 stopserver($server, "$pid2");
1337 displaylogs($testnumcheck);
1338 $doesntrun{$pidfile} = 1;
1342 # Server is up. Verify that we can speak to it.
1343 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1345 logmsg "RUN: $srvrname server failed verification\n";
1346 # failed to talk to it properly. Kill the server and return failure
1347 stopserver($server, "$httppid $pid2");
1348 displaylogs($testnumcheck);
1349 $doesntrun{$pidfile} = 1;
1355 logmsg "RUN: $srvrname server is now running PID $httppid\n";
1360 return ($httppid, $pid2);
1363 #######################################################################
1364 # start the https stunnel based server
1366 sub runhttpsserver {
1367 my ($verbose, $ipv6, $certfile) = @_;
1368 my $proto = 'https';
1369 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1370 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
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 $certfile = 'stunnel.pem' unless($certfile);
1401 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1403 $flags .= "--verbose " if($debugprotocol);
1404 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1405 $flags .= "--id $idnum " if($idnum > 1);
1406 $flags .= "--ipv$ipvnum --proto $proto ";
1407 $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
1408 $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
1409 $flags .= "--connect $HTTPPORT --accept $HTTPSPORT";
1411 my $cmd = "$perl $srcdir/secureserver.pl $flags";
1412 my ($httpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1414 if($httpspid <= 0 || !pidexists($httpspid)) {
1416 logmsg "RUN: failed to start the $srvrname server\n";
1417 stopserver($server, "$pid2");
1418 displaylogs($testnumcheck);
1419 $doesntrun{$pidfile} = 1;
1423 # Server is up. Verify that we can speak to it.
1424 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $HTTPSPORT);
1426 logmsg "RUN: $srvrname server failed verification\n";
1427 # failed to talk to it properly. Kill the server and return failure
1428 stopserver($server, "$httpspid $pid2");
1429 displaylogs($testnumcheck);
1430 $doesntrun{$pidfile} = 1;
1433 # Here pid3 is actually the pid returned by the unsecure-http server.
1435 $runcert{$server} = $certfile;
1438 logmsg "RUN: $srvrname server is now running PID $httpspid\n";
1443 return ($httpspid, $pid2);
1446 #######################################################################
1447 # start the non-stunnel HTTP TLS extensions capable server
1449 sub runhttptlsserver {
1450 my ($verbose, $ipv6) = @_;
1451 my $proto = "httptls";
1452 my $port = ($ipv6 && ($ipv6 =~ /6$/)) ? $HTTPTLS6PORT : $HTTPTLSPORT;
1453 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1454 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1466 $server = servername_id($proto, $ipvnum, $idnum);
1468 $pidfile = $serverpidfile{$server};
1470 # don't retry if the server doesn't work
1471 if ($doesntrun{$pidfile}) {
1475 my $pid = processexists($pidfile);
1477 stopserver($server, "$pid");
1479 unlink($pidfile) if(-f $pidfile);
1481 $srvrname = servername_str($proto, $ipvnum, $idnum);
1483 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1485 $flags .= "--http ";
1486 $flags .= "--debug 1 " if($debugprotocol);
1487 $flags .= "--port $port ";
1488 $flags .= "--priority NORMAL:+SRP ";
1489 $flags .= "--srppasswd $srcdir/certs/srp-verifier-db ";
1490 $flags .= "--srppasswdconf $srcdir/certs/srp-verifier-conf";
1492 my $cmd = "$httptlssrv $flags > $logfile 2>&1";
1493 my ($httptlspid, $pid2) = startnew($cmd, $pidfile, 10, 1); # fake pidfile
1495 if($httptlspid <= 0 || !pidexists($httptlspid)) {
1497 logmsg "RUN: failed to start the $srvrname server\n";
1498 stopserver($server, "$pid2");
1499 displaylogs($testnumcheck);
1500 $doesntrun{$pidfile} = 1;
1504 # Server is up. Verify that we can speak to it. PID is from fake pidfile
1505 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1507 logmsg "RUN: $srvrname server failed verification\n";
1508 # failed to talk to it properly. Kill the server and return failure
1509 stopserver($server, "$httptlspid $pid2");
1510 displaylogs($testnumcheck);
1511 $doesntrun{$pidfile} = 1;
1517 logmsg "RUN: $srvrname server is now running PID $httptlspid\n";
1522 return ($httptlspid, $pid2);
1525 #######################################################################
1526 # start the pingpong server (FTP, POP3, IMAP, SMTP)
1528 sub runpingpongserver {
1529 my ($proto, $id, $verbose, $ipv6) = @_;
1531 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1532 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1533 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1540 if($proto eq "ftp") {
1541 $port = ($idnum>1)?$FTP2PORT:$FTPPORT;
1544 # if IPv6, use a different setup
1548 elsif($proto eq "pop3") {
1549 $port = ($ipvnum==6) ? $POP36PORT : $POP3PORT;
1551 elsif($proto eq "imap") {
1552 $port = ($ipvnum==6) ? $IMAP6PORT : $IMAPPORT;
1554 elsif($proto eq "smtp") {
1555 $port = ($ipvnum==6) ? $SMTP6PORT : $SMTPPORT;
1558 print STDERR "Unsupported protocol $proto!!\n";
1562 $server = servername_id($proto, $ipvnum, $idnum);
1564 $pidfile = $serverpidfile{$server};
1566 # don't retry if the server doesn't work
1567 if ($doesntrun{$pidfile}) {
1571 my $pid = processexists($pidfile);
1573 stopserver($server, "$pid");
1575 unlink($pidfile) if(-f $pidfile);
1577 $srvrname = servername_str($proto, $ipvnum, $idnum);
1579 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1581 $flags .= "--verbose " if($debugprotocol);
1582 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1583 $flags .= "--srcdir \"$srcdir\" --proto $proto ";
1584 $flags .= "--id $idnum " if($idnum > 1);
1585 $flags .= "--ipv$ipvnum --port $port --addr \"$ip\"";
1587 my $cmd = "$perl $srcdir/ftpserver.pl $flags";
1588 my ($ftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1590 if($ftppid <= 0 || !pidexists($ftppid)) {
1592 logmsg "RUN: failed to start the $srvrname server\n";
1593 stopserver($server, "$pid2");
1594 displaylogs($testnumcheck);
1595 $doesntrun{$pidfile} = 1;
1599 # Server is up. Verify that we can speak to it.
1600 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1602 logmsg "RUN: $srvrname server failed verification\n";
1603 # failed to talk to it properly. Kill the server and return failure
1604 stopserver($server, "$ftppid $pid2");
1605 displaylogs($testnumcheck);
1606 $doesntrun{$pidfile} = 1;
1613 logmsg "RUN: $srvrname server is now running PID $ftppid\n";
1618 return ($pid2, $ftppid);
1621 #######################################################################
1622 # start the ftps server (or rather, tunnel)
1625 my ($verbose, $ipv6, $certfile) = @_;
1627 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1628 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1640 $server = servername_id($proto, $ipvnum, $idnum);
1642 $pidfile = $serverpidfile{$server};
1644 # don't retry if the server doesn't work
1645 if ($doesntrun{$pidfile}) {
1649 my $pid = processexists($pidfile);
1651 stopserver($server, "$pid");
1653 unlink($pidfile) if(-f $pidfile);
1655 $srvrname = servername_str($proto, $ipvnum, $idnum);
1657 $certfile = 'stunnel.pem' unless($certfile);
1659 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1661 $flags .= "--verbose " if($debugprotocol);
1662 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1663 $flags .= "--id $idnum " if($idnum > 1);
1664 $flags .= "--ipv$ipvnum --proto $proto ";
1665 $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
1666 $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
1667 $flags .= "--connect $FTPPORT --accept $FTPSPORT";
1669 my $cmd = "$perl $srcdir/secureserver.pl $flags";
1670 my ($ftpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1672 if($ftpspid <= 0 || !pidexists($ftpspid)) {
1674 logmsg "RUN: failed to start the $srvrname server\n";
1675 stopserver($server, "$pid2");
1676 displaylogs($testnumcheck);
1677 $doesntrun{$pidfile} = 1;
1681 # Server is up. Verify that we can speak to it.
1682 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $FTPSPORT);
1684 logmsg "RUN: $srvrname server failed verification\n";
1685 # failed to talk to it properly. Kill the server and return failure
1686 stopserver($server, "$ftpspid $pid2");
1687 displaylogs($testnumcheck);
1688 $doesntrun{$pidfile} = 1;
1691 # Here pid3 is actually the pid returned by the unsecure-ftp server.
1693 $runcert{$server} = $certfile;
1696 logmsg "RUN: $srvrname server is now running PID $ftpspid\n";
1701 return ($ftpspid, $pid2);
1704 #######################################################################
1705 # start the tftp server
1708 my ($id, $verbose, $ipv6) = @_;
1709 my $port = $TFTPPORT;
1713 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1721 # if IPv6, use a different setup
1727 $server = servername_id($proto, $ipvnum, $idnum);
1729 $pidfile = $serverpidfile{$server};
1731 # don't retry if the server doesn't work
1732 if ($doesntrun{$pidfile}) {
1736 my $pid = processexists($pidfile);
1738 stopserver($server, "$pid");
1740 unlink($pidfile) if(-f $pidfile);
1742 $srvrname = servername_str($proto, $ipvnum, $idnum);
1744 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1746 $flags .= "--verbose " if($debugprotocol);
1747 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1748 $flags .= "--id $idnum " if($idnum > 1);
1749 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1751 my $cmd = "$perl $srcdir/tftpserver.pl $flags";
1752 my ($tftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1754 if($tftppid <= 0 || !pidexists($tftppid)) {
1756 logmsg "RUN: failed to start the $srvrname server\n";
1757 stopserver($server, "$pid2");
1758 displaylogs($testnumcheck);
1759 $doesntrun{$pidfile} = 1;
1763 # Server is up. Verify that we can speak to it.
1764 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1766 logmsg "RUN: $srvrname server failed verification\n";
1767 # failed to talk to it properly. Kill the server and return failure
1768 stopserver($server, "$tftppid $pid2");
1769 displaylogs($testnumcheck);
1770 $doesntrun{$pidfile} = 1;
1776 logmsg "RUN: $srvrname server is now running PID $tftppid\n";
1781 return ($pid2, $tftppid);
1785 #######################################################################
1786 # start the rtsp server
1789 my ($verbose, $ipv6) = @_;
1790 my $port = $RTSPPORT;
1802 # if IPv6, use a different setup
1808 $server = servername_id($proto, $ipvnum, $idnum);
1810 $pidfile = $serverpidfile{$server};
1812 # don't retry if the server doesn't work
1813 if ($doesntrun{$pidfile}) {
1817 my $pid = processexists($pidfile);
1819 stopserver($server, "$pid");
1821 unlink($pidfile) if(-f $pidfile);
1823 $srvrname = servername_str($proto, $ipvnum, $idnum);
1825 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1827 $flags .= "--verbose " if($debugprotocol);
1828 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1829 $flags .= "--id $idnum " if($idnum > 1);
1830 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1832 my $cmd = "$perl $srcdir/rtspserver.pl $flags";
1833 my ($rtsppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1835 if($rtsppid <= 0 || !pidexists($rtsppid)) {
1837 logmsg "RUN: failed to start the $srvrname server\n";
1838 stopserver($server, "$pid2");
1839 displaylogs($testnumcheck);
1840 $doesntrun{$pidfile} = 1;
1844 # Server is up. Verify that we can speak to it.
1845 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1847 logmsg "RUN: $srvrname server failed verification\n";
1848 # failed to talk to it properly. Kill the server and return failure
1849 stopserver($server, "$rtsppid $pid2");
1850 displaylogs($testnumcheck);
1851 $doesntrun{$pidfile} = 1;
1857 logmsg "RUN: $srvrname server is now running PID $rtsppid\n";
1862 return ($rtsppid, $pid2);
1866 #######################################################################
1867 # Start the ssh (scp/sftp) server
1870 my ($id, $verbose, $ipv6) = @_;
1872 my $port = $SSHPORT;
1873 my $socksport = $SOCKSPORT;
1876 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1883 $server = servername_id($proto, $ipvnum, $idnum);
1885 $pidfile = $serverpidfile{$server};
1887 # don't retry if the server doesn't work
1888 if ($doesntrun{$pidfile}) {
1892 my $pid = processexists($pidfile);
1894 stopserver($server, "$pid");
1896 unlink($pidfile) if(-f $pidfile);
1898 $srvrname = servername_str($proto, $ipvnum, $idnum);
1900 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1902 $flags .= "--verbose " if($verbose);
1903 $flags .= "--debugprotocol " if($debugprotocol);
1904 $flags .= "--pidfile \"$pidfile\" ";
1905 $flags .= "--id $idnum " if($idnum > 1);
1906 $flags .= "--ipv$ipvnum --addr \"$ip\" ";
1907 $flags .= "--sshport $port --socksport $socksport ";
1908 $flags .= "--user \"$USER\"";
1910 my $cmd = "$perl $srcdir/sshserver.pl $flags";
1911 my ($sshpid, $pid2) = startnew($cmd, $pidfile, 60, 0);
1913 # on loaded systems sshserver start up can take longer than the timeout
1914 # passed to startnew, when this happens startnew completes without being
1915 # able to read the pidfile and consequently returns a zero pid2 above.
1917 if($sshpid <= 0 || !pidexists($sshpid)) {
1919 logmsg "RUN: failed to start the $srvrname server\n";
1920 stopserver($server, "$pid2");
1921 $doesntrun{$pidfile} = 1;
1925 # ssh server verification allows some extra time for the server to start up
1926 # and gives us the opportunity of recovering the pid from the pidfile, when
1927 # this verification succeeds the recovered pid is assigned to pid2.
1929 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1931 logmsg "RUN: $srvrname server failed verification\n";
1932 # failed to fetch server pid. Kill the server and return failure
1933 stopserver($server, "$sshpid $pid2");
1934 $doesntrun{$pidfile} = 1;
1939 # once it is known that the ssh server is alive, sftp server verification
1940 # is performed actually connecting to it, authenticating and performing a
1941 # very simple remote command. This verification is tried only one time.
1943 $sshdlog = server_logfilename($LOGDIR, 'ssh', $ipvnum, $idnum);
1944 $sftplog = server_logfilename($LOGDIR, 'sftp', $ipvnum, $idnum);
1946 if(verifysftp('sftp', $ipvnum, $idnum, $ip, $port) < 1) {
1947 logmsg "RUN: SFTP server failed verification\n";
1948 # failed to talk to it properly. Kill the server and return failure
1950 display_sftpconfig();
1952 display_sshdconfig();
1953 stopserver($server, "$sshpid $pid2");
1954 $doesntrun{$pidfile} = 1;
1959 logmsg "RUN: $srvrname server is now running PID $pid2\n";
1962 return ($pid2, $sshpid);
1965 #######################################################################
1966 # Start the socks server
1968 sub runsocksserver {
1969 my ($id, $verbose, $ipv6) = @_;
1971 my $port = $SOCKSPORT;
1972 my $proto = 'socks';
1974 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1981 $server = servername_id($proto, $ipvnum, $idnum);
1983 $pidfile = $serverpidfile{$server};
1985 # don't retry if the server doesn't work
1986 if ($doesntrun{$pidfile}) {
1990 my $pid = processexists($pidfile);
1992 stopserver($server, "$pid");
1994 unlink($pidfile) if(-f $pidfile);
1996 $srvrname = servername_str($proto, $ipvnum, $idnum);
1998 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
2000 # The ssh server must be already running
2002 logmsg "RUN: SOCKS server cannot find running SSH server\n";
2003 $doesntrun{$pidfile} = 1;
2007 # Find out ssh daemon canonical file name
2008 my $sshd = find_sshd();
2010 logmsg "RUN: SOCKS server cannot find $sshdexe\n";
2011 $doesntrun{$pidfile} = 1;
2015 # Find out ssh daemon version info
2016 ($sshdid, $sshdvernum, $sshdverstr, $sshderror) = sshversioninfo($sshd);
2018 # Not an OpenSSH or SunSSH ssh daemon
2019 logmsg "$sshderror\n" if($verbose);
2020 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
2021 $doesntrun{$pidfile} = 1;
2024 logmsg "ssh server found $sshd is $sshdverstr\n" if($verbose);
2026 # Find out ssh client canonical file name
2027 my $ssh = find_ssh();
2029 logmsg "RUN: SOCKS server cannot find $sshexe\n";
2030 $doesntrun{$pidfile} = 1;
2034 # Find out ssh client version info
2035 my ($sshid, $sshvernum, $sshverstr, $ssherror) = sshversioninfo($ssh);
2037 # Not an OpenSSH or SunSSH ssh client
2038 logmsg "$ssherror\n" if($verbose);
2039 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
2040 $doesntrun{$pidfile} = 1;
2044 # Verify minimum ssh client version
2045 if((($sshid =~ /OpenSSH/) && ($sshvernum < 299)) ||
2046 (($sshid =~ /SunSSH/) && ($sshvernum < 100))) {
2047 logmsg "ssh client found $ssh is $sshverstr\n";
2048 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
2049 $doesntrun{$pidfile} = 1;
2052 logmsg "ssh client found $ssh is $sshverstr\n" if($verbose);
2054 # Verify if ssh client and ssh daemon versions match
2055 if(($sshdid ne $sshid) || ($sshdvernum != $sshvernum)) {
2056 # Our test harness might work with slightly mismatched versions
2057 logmsg "Warning: version mismatch: sshd $sshdverstr - ssh $sshverstr\n"
2061 # Config file options for ssh client are previously set from sshserver.pl
2062 if(! -e $sshconfig) {
2063 logmsg "RUN: SOCKS server cannot find $sshconfig\n";
2064 $doesntrun{$pidfile} = 1;
2068 $sshlog = server_logfilename($LOGDIR, 'socks', $ipvnum, $idnum);
2070 # start our socks server
2071 my $cmd="\"$ssh\" -N -F $sshconfig $ip > $sshlog 2>&1";
2072 my ($sshpid, $pid2) = startnew($cmd, $pidfile, 30, 1); # fake pidfile
2074 if($sshpid <= 0 || !pidexists($sshpid)) {
2076 logmsg "RUN: failed to start the $srvrname server\n";
2078 display_sshconfig();
2080 display_sshdconfig();
2081 stopserver($server, "$pid2");
2082 $doesntrun{$pidfile} = 1;
2086 # Ugly hack but ssh doesn't support pid files. PID is from fake pidfile.
2087 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
2089 logmsg "RUN: $srvrname server failed verification\n";
2090 # failed to talk to it properly. Kill the server and return failure
2091 stopserver($server, "$sshpid $pid2");
2092 $doesntrun{$pidfile} = 1;
2098 logmsg "RUN: $srvrname server is now running PID $pid2\n";
2101 return ($pid2, $sshpid);
2104 #######################################################################
2105 # Single shot http and gopher server responsiveness test. This should only
2106 # be used to verify that a server present in %run hash is still functional
2108 sub responsive_http_server {
2109 my ($proto, $verbose, $alt, $port_or_path) = @_;
2114 if($alt eq "ipv6") {
2115 # if IPv6, use a different setup
2119 elsif($alt eq "proxy") {
2122 elsif($alt eq "unix") {
2123 # IP (protocol) is mutually exclusive with Unix sockets
2127 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
2130 #######################################################################
2131 # Single shot pingpong server responsiveness test. This should only be
2132 # used to verify that a server present in %run hash is still functional
2134 sub responsive_pingpong_server {
2135 my ($proto, $id, $verbose, $ipv6) = @_;
2137 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
2138 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
2139 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
2141 if($proto eq "ftp") {
2142 $port = ($idnum>1)?$FTP2PORT:$FTPPORT;
2145 # if IPv6, use a different setup
2149 elsif($proto eq "pop3") {
2150 $port = ($ipvnum==6) ? $POP36PORT : $POP3PORT;
2152 elsif($proto eq "imap") {
2153 $port = ($ipvnum==6) ? $IMAP6PORT : $IMAPPORT;
2155 elsif($proto eq "smtp") {
2156 $port = ($ipvnum==6) ? $SMTP6PORT : $SMTPPORT;
2159 print STDERR "Unsupported protocol $proto!!\n";
2163 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2166 #######################################################################
2167 # Single shot rtsp server responsiveness test. This should only be
2168 # used to verify that a server present in %run hash is still functional
2170 sub responsive_rtsp_server {
2171 my ($verbose, $ipv6) = @_;
2172 my $port = $RTSPPORT;
2179 # if IPv6, use a different setup
2185 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2188 #######################################################################
2189 # Single shot tftp server responsiveness test. This should only be
2190 # used to verify that a server present in %run hash is still functional
2192 sub responsive_tftp_server {
2193 my ($id, $verbose, $ipv6) = @_;
2194 my $port = $TFTPPORT;
2198 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
2201 # if IPv6, use a different setup
2207 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2210 #######################################################################
2211 # Single shot non-stunnel HTTP TLS extensions capable server
2212 # responsiveness test. This should only be used to verify that a
2213 # server present in %run hash is still functional
2215 sub responsive_httptls_server {
2216 my ($verbose, $ipv6) = @_;
2217 my $proto = "httptls";
2218 my $port = ($ipv6 && ($ipv6 =~ /6$/)) ? $HTTPTLS6PORT : $HTTPTLSPORT;
2219 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
2220 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
2223 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2226 #######################################################################
2227 # Remove all files in the specified directory
2235 opendir(DIR, $dir) ||
2236 return 0; # can't open dir
2237 while($file = readdir(DIR)) {
2238 if($file !~ /^\./) {
2239 unlink("$dir/$file");
2247 #######################################################################
2248 # compare test results with the expected output, we might filter off
2249 # some pattern that is allowed to differ, output test results
2252 my ($testnum, $testname, $subject, $firstref, $secondref)=@_;
2254 my $result = compareparts($firstref, $secondref);
2257 # timestamp test result verification end
2258 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2261 logmsg "\n $testnum: $subject FAILED:\n";
2262 logmsg showdiff($LOGDIR, $firstref, $secondref);
2264 elsif(!$automakestyle) {
2269 logmsg "FAIL: $testnum - $testname - $subject\n";
2275 #######################################################################
2276 # display information about curl and the host the test suite runs on
2280 unlink($memdump); # remove this if there was one left
2289 my $curlverout="$LOGDIR/curlverout.log";
2290 my $curlvererr="$LOGDIR/curlvererr.log";
2291 my $versioncmd="$CURL --version 1>$curlverout 2>$curlvererr";
2293 unlink($curlverout);
2294 unlink($curlvererr);
2296 $versretval = runclient($versioncmd);
2299 open(VERSOUT, "<$curlverout");
2300 @version = <VERSOUT>;
2309 $curl =~ s/^(.*)(libcurl.*)/$1/g;
2312 if($curl =~ /mingw32/) {
2313 # This is a windows minw32 build, we need to translate the
2314 # given path to the "actual" windows path. The MSYS shell
2315 # has a builtin 'pwd -W' command which converts the path.
2316 $pwd = `sh -c "echo \$(pwd -W)"`;
2319 elsif ($curl =~ /win32/) {
2320 # Native Windows builds don't understand the
2321 # output of cygwin's pwd. It will be
2322 # something like /cygdrive/c/<some path>.
2324 # Use the cygpath utility to convert the
2325 # working directory to a Windows friendly
2326 # path. The -m option converts to use drive
2327 # letter:, but it uses / instead \. Forward
2328 # slashes (/) are easier for us. We don't
2329 # have to escape them to get them to curl
2331 chomp($pwd = `cygpath -m $pwd`);
2333 if ($libcurl =~ /winssl/i) {
2337 elsif ($libcurl =~ /openssl/i) {
2342 elsif ($libcurl =~ /gnutls/i) {
2347 elsif ($libcurl =~ /nss/i) {
2352 elsif ($libcurl =~ /(yassl|wolfssl)/i) {
2357 elsif ($libcurl =~ /polarssl/i) {
2361 elsif ($libcurl =~ /axtls/i) {
2365 elsif ($libcurl =~ /securetransport/i) {
2367 $ssllib="DarwinSSL";
2369 elsif ($libcurl =~ /BoringSSL/i) {
2371 $ssllib="BoringSSL";
2373 elsif ($libcurl =~ /libressl/i) {
2377 if ($libcurl =~ /ares/i) {
2382 elsif($_ =~ /^Protocols: (.*)/i) {
2383 # these are the protocols compiled in to this libcurl
2384 @protocols = split(' ', lc($1));
2386 # Generate a "proto-ipv6" version of each protocol to match the
2387 # IPv6 <server> name and a "proto-unix" to match the variant which
2388 # uses Unix domain sockets. This works even if support isn't
2389 # compiled in because the <features> test will fail.
2390 push @protocols, map(("$_-ipv6", "$_-unix"), @protocols);
2392 # 'http-proxy' is used in test cases to do CONNECT through
2393 push @protocols, 'http-proxy';
2395 # 'http-pipe' is the special server for testing pipelining
2396 push @protocols, 'http-pipe';
2398 # 'none' is used in test cases to mean no server
2399 push @protocols, 'none';
2401 elsif($_ =~ /^Features: (.*)/i) {
2403 if($feat =~ /TrackMemory/i) {
2404 # built with memory tracking support (--enable-curldebug)
2405 $has_memory_tracking = 1;
2407 if($feat =~ /debug/i) {
2408 # curl was built with --enable-debug
2411 if($feat =~ /SSL/i) {
2415 if($feat =~ /Largefile/i) {
2416 # large file support
2419 if($feat =~ /IDN/i) {
2423 if($feat =~ /IPv6/i) {
2426 if($feat =~ /UnixSockets/i) {
2429 if($feat =~ /libz/i) {
2432 if($feat =~ /NTLM/i) {
2436 # Use this as a proxy for any cryptographic authentication
2439 if($feat =~ /NTLM_WB/i) {
2440 # NTLM delegation to winbind daemon ntlm_auth helper enabled
2443 if($feat =~ /SSPI/i) {
2447 if($feat =~ /GSS-API/i) {
2451 if($feat =~ /Kerberos/i) {
2455 # Use this as a proxy for any cryptographic authentication
2458 if($feat =~ /SPNEGO/i) {
2462 # Use this as a proxy for any cryptographic authentication
2465 if($feat =~ /CharConv/i) {
2469 if($feat =~ /TLS-SRP/i) {
2473 if($feat =~ /Metalink/i) {
2477 if($feat =~ /AsynchDNS/i) {
2479 # this means threaded resolver
2481 $resolver="threaded";
2484 if($feat =~ /HTTP2/) {
2490 # Test harness currently uses a non-stunnel server in order to
2491 # run HTTP TLS-SRP tests required when curl is built with https
2492 # protocol support and TLS-SRP feature enabled. For convenience
2493 # 'httptls' may be included in the test harness protocols array
2494 # to differentiate this from classic stunnel based 'https' test
2500 if($_ =~ /^https(-ipv6|)$/) {
2505 if($add_httptls && (! grep /^httptls$/, @protocols)) {
2506 push @protocols, 'httptls';
2507 push @protocols, 'httptls-ipv6';
2512 logmsg "unable to get curl's version, further details are:\n";
2513 logmsg "issued command: \n";
2514 logmsg "$versioncmd \n";
2515 if ($versretval == -1) {
2516 logmsg "command failed with: \n";
2517 logmsg "$versnoexec \n";
2519 elsif ($versretval & 127) {
2520 logmsg sprintf("command died with signal %d, and %s coredump.\n",
2521 ($versretval & 127), ($versretval & 128)?"a":"no");
2524 logmsg sprintf("command exited with value %d \n", $versretval >> 8);
2526 logmsg "contents of $curlverout: \n";
2527 displaylogcontent("$curlverout");
2528 logmsg "contents of $curlvererr: \n";
2529 displaylogcontent("$curlvererr");
2530 die "couldn't get curl's version";
2533 if(-r "../lib/curl_config.h") {
2534 open(CONF, "<../lib/curl_config.h");
2536 if($_ =~ /^\#define HAVE_GETRLIMIT/) {
2544 # client has IPv6 support
2546 # check if the HTTP server has it!
2547 my @sws = `server/sws --version`;
2548 if($sws[0] =~ /IPv6/) {
2549 # HTTP server has IPv6 support!
2554 # check if the FTP server has it!
2555 @sws = `server/sockfilt --version`;
2556 if($sws[0] =~ /IPv6/) {
2557 # FTP server has IPv6 support!
2563 # client has Unix sockets support, check whether the HTTP server has it
2564 my @sws = `server/sws --version`;
2565 $http_unix = 1 if($sws[0] =~ /unix/);
2568 if(!$has_memory_tracking && $torture) {
2569 die "can't run torture tests since curl was built without ".
2570 "TrackMemory feature (--enable-curldebug)";
2573 $has_shared = `sh $CURLCONFIG --built-shared`;
2576 my $hostname=join(' ', runclientoutput("hostname"));
2577 my $hosttype=join(' ', runclientoutput("uname -a"));
2579 logmsg ("********* System characteristics ******** \n",
2582 "* Features: $feat\n",
2583 "* Host: $hostname",
2584 "* System: $hosttype");
2586 if($has_memory_tracking && $has_threadedres) {
2587 $has_memory_tracking = 0;
2589 "*** DISABLES memory tracking when using threaded resolver\n",
2593 logmsg sprintf("* Server SSL: %8s", $stunnel?"ON ":"OFF");
2594 logmsg sprintf(" libcurl SSL: %s\n", $ssl_version?"ON ":"OFF");
2595 logmsg sprintf("* debug build: %8s", $debug_build?"ON ":"OFF");
2596 logmsg sprintf(" track memory: %s\n", $has_memory_tracking?"ON ":"OFF");
2597 logmsg sprintf("* valgrind: %8s", $valgrind?"ON ":"OFF");
2598 logmsg sprintf(" HTTP IPv6 %s\n", $http_ipv6?"ON ":"OFF");
2599 logmsg sprintf("* HTTP Unix %s\n", $http_unix?"ON ":"OFF");
2600 logmsg sprintf("* FTP IPv6 %8s", $ftp_ipv6?"ON ":"OFF");
2601 logmsg sprintf(" Libtool lib: %s\n", $libtool?"ON ":"OFF");
2602 logmsg sprintf("* Shared build: %-3s", $has_shared);
2603 logmsg sprintf(" Resolver: %s\n", $resolver);
2605 logmsg sprintf("* SSL library: %13s\n", $ssllib);
2608 logmsg "* Ports:\n";
2610 logmsg sprintf("* HTTP/%d ", $HTTPPORT);
2611 logmsg sprintf("FTP/%d ", $FTPPORT);
2612 logmsg sprintf("FTP2/%d ", $FTP2PORT);
2613 logmsg sprintf("RTSP/%d ", $RTSPPORT);
2615 logmsg sprintf("FTPS/%d ", $FTPSPORT);
2616 logmsg sprintf("HTTPS/%d ", $HTTPSPORT);
2618 logmsg sprintf("\n* TFTP/%d ", $TFTPPORT);
2620 logmsg sprintf("HTTP-IPv6/%d ", $HTTP6PORT);
2621 logmsg sprintf("RTSP-IPv6/%d ", $RTSP6PORT);
2624 logmsg sprintf("FTP-IPv6/%d ", $FTP6PORT);
2627 logmsg sprintf("TFTP-IPv6/%d ", $TFTP6PORT);
2629 logmsg sprintf("\n* GOPHER/%d ", $GOPHERPORT);
2631 logmsg sprintf("GOPHER-IPv6/%d", $GOPHERPORT);
2633 logmsg sprintf("\n* SSH/%d ", $SSHPORT);
2634 logmsg sprintf("SOCKS/%d ", $SOCKSPORT);
2635 logmsg sprintf("POP3/%d ", $POP3PORT);
2636 logmsg sprintf("IMAP/%d ", $IMAPPORT);
2637 logmsg sprintf("SMTP/%d\n", $SMTPPORT);
2639 logmsg sprintf("* POP3-IPv6/%d ", $POP36PORT);
2640 logmsg sprintf("IMAP-IPv6/%d ", $IMAP6PORT);
2641 logmsg sprintf("SMTP-IPv6/%d\n", $SMTP6PORT);
2644 logmsg sprintf("* HTTPTLS/%d ", $HTTPTLSPORT);
2646 logmsg sprintf("HTTPTLS-IPv6/%d ", $HTTPTLS6PORT);
2650 logmsg sprintf("* HTTP-PIPE/%d \n", $HTTPPIPEPORT);
2653 logmsg "* Unix socket paths:\n";
2655 logmsg sprintf("* HTTP-Unix:%s\n", $HTTPUNIXPATH);
2659 $has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys');
2661 logmsg "***************************************** \n";
2664 #######################################################################
2665 # substitute the variable stuff into either a joined up file or
2666 # a command, in either case passed by reference
2673 $$thing =~ s/%FTP6PORT/$FTP6PORT/g;
2674 $$thing =~ s/%FTP2PORT/$FTP2PORT/g;
2675 $$thing =~ s/%FTPSPORT/$FTPSPORT/g;
2676 $$thing =~ s/%FTPPORT/$FTPPORT/g;
2678 $$thing =~ s/%GOPHER6PORT/$GOPHER6PORT/g;
2679 $$thing =~ s/%GOPHERPORT/$GOPHERPORT/g;
2681 $$thing =~ s/%HTTPTLS6PORT/$HTTPTLS6PORT/g;
2682 $$thing =~ s/%HTTPTLSPORT/$HTTPTLSPORT/g;
2683 $$thing =~ s/%HTTP6PORT/$HTTP6PORT/g;
2684 $$thing =~ s/%HTTPSPORT/$HTTPSPORT/g;
2685 $$thing =~ s/%HTTPPORT/$HTTPPORT/g;
2686 $$thing =~ s/%HTTPPIPEPORT/$HTTPPIPEPORT/g;
2687 $$thing =~ s/%PROXYPORT/$HTTPPROXYPORT/g;
2689 $$thing =~ s/%IMAP6PORT/$IMAP6PORT/g;
2690 $$thing =~ s/%IMAPPORT/$IMAPPORT/g;
2692 $$thing =~ s/%POP36PORT/$POP36PORT/g;
2693 $$thing =~ s/%POP3PORT/$POP3PORT/g;
2695 $$thing =~ s/%RTSP6PORT/$RTSP6PORT/g;
2696 $$thing =~ s/%RTSPPORT/$RTSPPORT/g;
2698 $$thing =~ s/%SMTP6PORT/$SMTP6PORT/g;
2699 $$thing =~ s/%SMTPPORT/$SMTPPORT/g;
2701 $$thing =~ s/%SOCKSPORT/$SOCKSPORT/g;
2702 $$thing =~ s/%SSHPORT/$SSHPORT/g;
2704 $$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
2705 $$thing =~ s/%TFTPPORT/$TFTPPORT/g;
2707 # server Unix domain socket paths
2709 $$thing =~ s/%HTTPUNIXPATH/$HTTPUNIXPATH/g;
2711 # client IP addresses
2713 $$thing =~ s/%CLIENT6IP/$CLIENT6IP/g;
2714 $$thing =~ s/%CLIENTIP/$CLIENTIP/g;
2716 # server IP addresses
2718 $$thing =~ s/%HOST6IP/$HOST6IP/g;
2719 $$thing =~ s/%HOSTIP/$HOSTIP/g;
2723 $$thing =~ s/%CURL/$CURL/g;
2724 $$thing =~ s/%PWD/$pwd/g;
2725 $$thing =~ s/%SRCDIR/$srcdir/g;
2726 $$thing =~ s/%USER/$USER/g;
2728 # The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be
2729 # used for time-out tests and that whould work on most hosts as these
2730 # adjust for the startup/check time for this particular host. We needed
2731 # to do this to make the test suite run better on very slow hosts.
2733 my $ftp2 = $ftpchecktime * 2;
2734 my $ftp3 = $ftpchecktime * 3;
2736 $$thing =~ s/%FTPTIME2/$ftp2/g;
2737 $$thing =~ s/%FTPTIME3/$ftp3/g;
2741 $$thing =~ s/%H2CVER/$h2cver/g;
2753 #######################################################################
2754 # Provide time stamps for single test skipped events
2756 sub timestampskippedevents {
2757 my $testnum = $_[0];
2759 return if((not defined($testnum)) || ($testnum < 1));
2763 if($timevrfyend{$testnum}) {
2766 elsif($timesrvrlog{$testnum}) {
2767 $timevrfyend{$testnum} = $timesrvrlog{$testnum};
2770 elsif($timetoolend{$testnum}) {
2771 $timevrfyend{$testnum} = $timetoolend{$testnum};
2772 $timesrvrlog{$testnum} = $timetoolend{$testnum};
2774 elsif($timetoolini{$testnum}) {
2775 $timevrfyend{$testnum} = $timetoolini{$testnum};
2776 $timesrvrlog{$testnum} = $timetoolini{$testnum};
2777 $timetoolend{$testnum} = $timetoolini{$testnum};
2779 elsif($timesrvrend{$testnum}) {
2780 $timevrfyend{$testnum} = $timesrvrend{$testnum};
2781 $timesrvrlog{$testnum} = $timesrvrend{$testnum};
2782 $timetoolend{$testnum} = $timesrvrend{$testnum};
2783 $timetoolini{$testnum} = $timesrvrend{$testnum};
2785 elsif($timesrvrini{$testnum}) {
2786 $timevrfyend{$testnum} = $timesrvrini{$testnum};
2787 $timesrvrlog{$testnum} = $timesrvrini{$testnum};
2788 $timetoolend{$testnum} = $timesrvrini{$testnum};
2789 $timetoolini{$testnum} = $timesrvrini{$testnum};
2790 $timesrvrend{$testnum} = $timesrvrini{$testnum};
2792 elsif($timeprepini{$testnum}) {
2793 $timevrfyend{$testnum} = $timeprepini{$testnum};
2794 $timesrvrlog{$testnum} = $timeprepini{$testnum};
2795 $timetoolend{$testnum} = $timeprepini{$testnum};
2796 $timetoolini{$testnum} = $timeprepini{$testnum};
2797 $timesrvrend{$testnum} = $timeprepini{$testnum};
2798 $timesrvrini{$testnum} = $timeprepini{$testnum};
2803 #######################################################################
2804 # Run a single specified test case
2807 my ($evbased, # 1 means switch on if possible (and "curl" is tested)
2808 # returns "not a test" if it can't be used for this test
2817 my $disablevalgrind;
2819 # copy test number to a global scope var, this allows
2820 # testnum checking when starting test harness servers.
2821 $testnumcheck = $testnum;
2823 # timestamp test preparation start
2824 $timeprepini{$testnum} = Time::HiRes::time() if($timestats);
2826 if($disttests !~ /test$testnum\W/ ) {
2827 logmsg "Warning: test$testnum not present in tests/data/Makefile.inc\n";
2829 if($disabled{$testnum}) {
2830 logmsg "Warning: test$testnum is explicitly disabled\n";
2833 # load the test case file definition
2834 if(loadtest("${TESTDIR}/test${testnum}")) {
2836 # this is not a test
2837 logmsg "RUN: $testnum doesn't look like a test case\n";
2842 @what = getpart("client", "features");
2845 # We require a feature to be present
2850 if($f =~ /^([^!].*)$/) {
2851 # Store the feature for later
2859 elsif($1 eq "SSLpinning") {
2860 if($has_sslpinning) {
2864 elsif($1 eq "OpenSSL") {
2869 elsif($1 eq "GnuTLS") {
2874 elsif($1 eq "NSS") {
2879 elsif($1 eq "axTLS") {
2884 elsif($1 eq "WinSSL") {
2889 elsif($1 eq "DarwinSSL") {
2890 if($has_darwinssl) {
2894 elsif($1 eq "unittest") {
2899 elsif($1 eq "debug") {
2904 elsif($1 eq "TrackMemory") {
2905 if($has_memory_tracking) {
2909 elsif($1 eq "large_file") {
2914 elsif($1 eq "idn") {
2919 elsif($1 eq "ipv6") {
2924 elsif($1 eq "libz") {
2929 elsif($1 eq "NTLM") {
2934 elsif($1 eq "NTLM_WB") {
2939 elsif($1 eq "SSPI") {
2944 elsif($1 eq "GSS-API") {
2949 elsif($1 eq "Kerberos") {
2954 elsif($1 eq "SPNEGO") {
2959 elsif($1 eq "getrlimit") {
2960 if($has_getrlimit) {
2964 elsif($1 eq "crypto") {
2969 elsif($1 eq "TLS-SRP") {
2974 elsif($1 eq "Metalink") {
2979 elsif($1 eq "http2") {
2984 elsif($1 eq "socks") {
2987 elsif($1 eq "unix-sockets") {
2990 # See if this "feature" is in the list of supported protocols
2991 elsif (grep /^\Q$1\E$/i, @protocols) {
2995 $why = "curl lacks $1 support";
3000 # We require a feature to not be present
3006 if($f =~ /^!(.*)$/) {
3012 elsif($1 eq "OpenSSL") {
3017 elsif($1 eq "GnuTLS") {
3022 elsif($1 eq "NSS") {
3027 elsif($1 eq "axTLS") {
3032 elsif($1 eq "WinSSL") {
3037 elsif($1 eq "DarwinSSL") {
3038 if(!$has_darwinssl) {
3042 elsif($1 eq "TrackMemory") {
3043 if(!$has_memory_tracking) {
3047 elsif($1 eq "large_file") {
3052 elsif($1 eq "idn") {
3057 elsif($1 eq "ipv6") {
3062 elsif($1 eq "unix-sockets") {
3065 elsif($1 eq "libz") {
3070 elsif($1 eq "NTLM") {
3075 elsif($1 eq "NTLM_WB") {
3080 elsif($1 eq "SSPI") {
3085 elsif($1 eq "GSS-API") {
3090 elsif($1 eq "Kerberos") {
3091 if(!$has_kerberos) {
3095 elsif($1 eq "SPNEGO") {
3100 elsif($1 eq "getrlimit") {
3101 if(!$has_getrlimit) {
3105 elsif($1 eq "crypto") {
3110 elsif($1 eq "TLS-SRP") {
3115 elsif($1 eq "Metalink") {
3116 if(!$has_metalink) {
3128 $why = "curl has $1 support";
3134 my @keywords = getpart("info", "keywords");
3139 $why = "missing the <keywords> section!";
3142 for $k (@keywords) {
3144 if ($disabled_keywords{$k}) {
3145 $why = "disabled by keyword";
3146 } elsif ($enabled_keywords{$k}) {
3151 if(!$why && !$match && %enabled_keywords) {
3152 $why = "disabled by missing keyword";
3156 # test definition may instruct to (un)set environment vars
3157 # this is done this early, so that the precheck can use environment
3158 # variables and still bail out fine on errors
3160 # restore environment variables that were modified in a previous run
3161 foreach my $var (keys %oldenv) {
3162 if($oldenv{$var} eq 'notset') {
3163 delete $ENV{$var} if($ENV{$var});
3166 $ENV{$var} = $oldenv{$var};
3168 delete $oldenv{$var};
3171 # remove test server commands file before servers are started/verified
3172 unlink($FTPDCMD) if(-f $FTPDCMD);
3174 # timestamp required servers verification start
3175 $timesrvrini{$testnum} = Time::HiRes::time() if($timestats);
3178 $why = serverfortest($testnum);
3181 # timestamp required servers verification end
3182 $timesrvrend{$testnum} = Time::HiRes::time() if($timestats);
3184 my @setenv = getpart("client", "setenv");
3186 foreach my $s (@setenv) {
3189 if($s =~ /([^=]*)=(.*)/) {
3190 my ($var, $content) = ($1, $2);
3191 # remember current setting, to restore it once test runs
3192 $oldenv{$var} = ($ENV{$var})?"$ENV{$var}":'notset';
3195 delete $ENV{$var} if($ENV{$var});
3198 if($var =~ /^LD_PRELOAD/) {
3199 if(exe_ext() && (exe_ext() eq '.exe')) {
3200 # print "Skipping LD_PRELOAD due to lack of OS support\n";
3203 if($debug_build || ($has_shared ne "yes")) {
3204 # print "Skipping LD_PRELOAD due to no release shared build\n";
3208 $ENV{$var} = "$content";
3216 # Add a precheck cache. If a precheck command was already invoked
3217 # exactly like this, then use the previous result to speed up
3218 # successive test invokes!
3220 my @precheck = getpart("client", "precheck");
3222 $cmd = $precheck[0];
3226 my @p = split(/ /, $cmd);
3228 # the first word, the command, does not contain a slash so
3229 # we will scan the "improved" PATH to find the command to
3231 my $fullp = checktestcmd($p[0]);
3236 $cmd = join(" ", @p);
3239 my @o = `$cmd 2>/dev/null`;
3244 $why = "precheck command error";
3246 logmsg "prechecked $cmd\n" if($verbose);
3251 if($why && !$listonly) {
3252 # there's a problem, count it as "skipped"
3255 $teststat[$testnum]=$why; # store reason for this test case
3258 if($skipped{$why} <= 3) {
3259 # show only the first three skips for each reason
3260 logmsg sprintf("test %04d SKIPPED: $why\n", $testnum);
3264 timestampskippedevents($testnum);
3267 logmsg sprintf("test %04d...", $testnum) if(!$automakestyle);
3269 # extract the reply data
3270 my @reply = getpart("reply", "data");
3271 my @replycheck = getpart("reply", "datacheck");
3273 my %replyattr = getpartattr("reply", "data");
3274 my %replycheckattr = getpartattr("reply", "datacheck");
3277 # we use this file instead to check the final output against
3279 if($replycheckattr{'nonewline'}) {
3280 # Yes, we must cut off the final newline from the final line
3282 chomp($replycheck[$#replycheck]);
3284 if($replycheckattr{'mode'}) {
3285 $replyattr{'mode'} = $replycheckattr{'mode'};
3291 # this is the valid protocol blurb curl should generate
3292 my @protocol= fixarray ( getpart("verify", "protocol") );
3294 # this is the valid protocol blurb curl should generate to a proxy
3295 my @proxyprot = fixarray ( getpart("verify", "proxy") );
3297 # redirected stdout/stderr to these files
3298 $STDOUT="$LOGDIR/stdout$testnum";
3299 $STDERR="$LOGDIR/stderr$testnum";
3301 # if this section exists, we verify that the stdout contained this:
3302 my @validstdout = fixarray ( getpart("verify", "stdout") );
3304 # if this section exists, we verify upload
3305 my @upload = getpart("verify", "upload");
3307 # if this section exists, it might be FTP server instructions:
3308 my @ftpservercmd = getpart("reply", "servercmd");
3310 my $CURLOUT="$LOGDIR/curl$testnum.out"; # curl output if not stdout
3313 my @testname= getpart("client", "name");
3314 my $testname = $testname[0];
3315 $testname =~ s/\n//g;
3316 logmsg "[$testname]\n" if(!$short);
3319 timestampskippedevents($testnum);
3320 return 0; # look successful
3323 my @codepieces = getpart("client", "tool");
3327 $tool = $codepieces[0];
3331 # remove server output logfile
3337 # write the instructions to file
3338 writearray($FTPDCMD, \@ftpservercmd);
3341 # get the command line options to use
3343 ($cmd, @blaha)= getpart("client", "command");
3346 # make some nice replace operations
3347 $cmd =~ s/\n//g; # no newlines please
3348 # substitute variables in the command line
3352 # there was no command given, use something silly
3355 if($has_memory_tracking) {
3359 # create a (possibly-empty) file before starting the test
3360 my @inputfile=getpart("client", "file");
3361 my %fileattr = getpartattr("client", "file");
3362 my $filename=$fileattr{'name'};
3363 if(@inputfile || $filename) {
3365 logmsg "ERROR: section client=>file has no name attribute\n";
3366 timestampskippedevents($testnum);
3369 my $fileContent = join('', @inputfile);
3370 subVariables \$fileContent;
3371 # logmsg "DEBUG: writing file " . $filename . "\n";
3372 open(OUTFILE, ">$filename");
3373 binmode OUTFILE; # for crapage systems, use binary
3374 print OUTFILE $fileContent;
3378 my %cmdhash = getpartattr("client", "command");
3382 if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-output/)) {
3383 #We may slap on --output!
3384 if (!@validstdout) {
3385 $out=" --output $CURLOUT ";
3389 my $serverlogslocktimeout = $defserverlogslocktimeout;
3390 if($cmdhash{'timeout'}) {
3391 # test is allowed to override default server logs lock timeout
3392 if($cmdhash{'timeout'} =~ /(\d+)/) {
3393 $serverlogslocktimeout = $1 if($1 >= 0);
3397 my $postcommanddelay = $defpostcommanddelay;
3398 if($cmdhash{'delay'}) {
3399 # test is allowed to specify a delay after command is executed
3400 if($cmdhash{'delay'} =~ /(\d+)/) {
3401 $postcommanddelay = $1 if($1 > 0);
3407 my $cmdtype = $cmdhash{'type'} || "default";
3408 my $fail_due_event_based = $evbased;
3409 if($cmdtype eq "perl") {
3410 # run the command line prepended with "perl"
3416 elsif($cmdtype eq "shell") {
3417 # run the command line prepended with "/bin/sh"
3419 $CMDLINE = "/bin/sh ";
3424 # run curl, add suitable command line options
3425 $cmd = "-1 ".$cmd if(exists $feature{"SSL"} && ($has_axtls));
3428 if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-include/)) {
3429 $inc = " --include";
3432 $cmdargs = "$out$inc ";
3433 $cmdargs .= "--trace-ascii log/trace$testnum ";
3434 $cmdargs .= "--trace-time ";
3436 $cmdargs .= "--test-event ";
3437 $fail_due_event_based--;
3442 $cmdargs = " $cmd"; # $cmd is the command line for the test file
3443 $CURLOUT = $STDOUT; # sends received data to stdout
3445 if($tool =~ /^lib/) {
3446 $CMDLINE="$LIBDIR/$tool";
3448 elsif($tool =~ /^unit/) {
3449 $CMDLINE="$UNITDIR/$tool";
3453 logmsg "The tool set in the test case for this: '$tool' does not exist\n";
3454 timestampskippedevents($testnum);
3461 # gdb is incompatible with valgrind, so disable it when debugging
3462 # Perhaps a better approach would be to run it under valgrind anyway
3463 # with --db-attach=yes or --vgdb=yes.
3467 if($fail_due_event_based) {
3468 logmsg "This test cannot run event based\n";
3472 my @stdintest = getpart("client", "stdin");
3475 my $stdinfile="$LOGDIR/stdin-for-$testnum";
3477 my %hash = getpartattr("client", "stdin");
3478 if($hash{'nonewline'}) {
3479 # cut off the final newline from the final line of the stdin data
3480 chomp($stdintest[$#stdintest]);
3483 writearray($stdinfile, \@stdintest);
3485 $cmdargs .= " <$stdinfile";
3493 if($valgrind && !$disablevalgrind) {
3494 my @valgrindoption = getpart("verify", "valgrind");
3495 if((!@valgrindoption) || ($valgrindoption[0] !~ /disable/)) {
3497 my $valgrindcmd = "$valgrind ";
3498 $valgrindcmd .= "$valgrind_tool " if($valgrind_tool);
3499 $valgrindcmd .= "--leak-check=yes ";
3500 $valgrindcmd .= "--suppressions=$srcdir/valgrind.supp ";
3501 # $valgrindcmd .= "--gen-suppressions=all ";
3502 $valgrindcmd .= "--num-callers=16 ";
3503 $valgrindcmd .= "${valgrind_logfile}=$LOGDIR/valgrind$testnum";
3504 $CMDLINE = "$valgrindcmd $CMDLINE";
3508 $CMDLINE .= "$cmdargs >$STDOUT 2>$STDERR";
3511 logmsg "$CMDLINE\n";
3514 print CMDLOG "$CMDLINE\n";
3521 # Apr 2007: precommand isn't being used and could be removed
3522 my @precommand= getpart("client", "precommand");
3523 if($precommand[0]) {
3524 # this is pure perl to eval!
3525 my $code = join("", @precommand);
3528 logmsg "perl: $code\n";
3529 logmsg "precommand: $@";
3530 stopservers($verbose);
3531 timestampskippedevents($testnum);
3537 my $gdbinit = "$TESTDIR/gdbinit$testnum";
3538 open(GDBCMD, ">$LOGDIR/gdbcmd");
3539 print GDBCMD "set args $cmdargs\n";
3540 print GDBCMD "show args\n";
3541 print GDBCMD "source $gdbinit\n" if -e $gdbinit;
3545 # timestamp starting of test command
3546 $timetoolini{$testnum} = Time::HiRes::time() if($timestats);
3548 # run the command line we built
3550 $cmdres = torture($CMDLINE,
3551 "$gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
3554 my $GDBW = ($gdbxwin) ? "-w" : "";
3555 runclient("$gdb --directory libtest $DBGCURL $GDBW -x $LOGDIR/gdbcmd");
3556 $cmdres=0; # makes it always continue after a debugged run
3559 $cmdres = runclient("$CMDLINE");
3560 my $signal_num = $cmdres & 127;
3561 $dumped_core = $cmdres & 128;
3563 if(!$anyway && ($signal_num || $dumped_core)) {
3568 $cmdres = (2000 + $signal_num) if($signal_num && !$cmdres);
3572 # timestamp finishing of test command
3573 $timetoolend{$testnum} = Time::HiRes::time() if($timestats);
3577 # there's core file present now!
3583 logmsg "core dumped\n";
3585 logmsg "running gdb for post-mortem analysis:\n";
3586 open(GDBCMD, ">$LOGDIR/gdbcmd2");
3587 print GDBCMD "bt\n";
3589 runclient("$gdb --directory libtest -x $LOGDIR/gdbcmd2 -batch $DBGCURL core ");
3590 # unlink("$LOGDIR/gdbcmd2");
3594 # If a server logs advisor read lock file exists, it is an indication
3595 # that the server has not yet finished writing out all its log files,
3596 # including server request log files used for protocol verification.
3597 # So, if the lock file exists the script waits here a certain amount
3598 # of time until the server removes it, or the given time expires.
3600 if($serverlogslocktimeout) {
3601 my $lockretry = $serverlogslocktimeout * 20;
3602 while((-f $SERVERLOGS_LOCK) && $lockretry--) {
3603 select(undef, undef, undef, 0.05);
3605 if(($lockretry < 0) &&
3606 ($serverlogslocktimeout >= $defserverlogslocktimeout)) {
3607 logmsg "Warning: server logs lock timeout ",
3608 "($serverlogslocktimeout seconds) expired\n";
3612 # Test harness ssh server does not have this synchronization mechanism,
3613 # this implies that some ssh server based tests might need a small delay
3614 # once that the client command has run to avoid false test failures.
3616 # gnutls-serv also lacks this synchronization mechanism, so gnutls-serv
3617 # based tests might need a small delay once that the client command has
3618 # run to avoid false test failures.
3620 sleep($postcommanddelay) if($postcommanddelay);
3622 # timestamp removal of server logs advisor read lock
3623 $timesrvrlog{$testnum} = Time::HiRes::time() if($timestats);
3625 # test definition might instruct to stop some servers
3626 # stop also all servers relative to the given one
3628 my @killtestservers = getpart("client", "killserver");
3629 if(@killtestservers) {
3631 # All servers relative to the given one must be stopped also
3634 foreach my $server (@killtestservers) {
3636 if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
3637 # given a stunnel ssl server, also kill non-ssl underlying one
3638 push @killservers, "${1}${2}";
3640 elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|-unix|))$/) {
3641 # given a non-ssl server, also kill stunnel piggybacking one
3642 push @killservers, "${1}s${2}";
3644 elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
3645 # given a socks server, also kill ssh underlying one
3646 push @killservers, "ssh${2}";
3648 elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
3649 # given a ssh server, also kill socks piggybacking one
3650 push @killservers, "socks${2}";
3652 push @killservers, $server;
3655 # kill sockfilter processes for pingpong relative servers
3657 foreach my $server (@killservers) {
3658 if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
3660 my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
3661 my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
3662 killsockfilters($proto, $ipvnum, $idnum, $verbose);
3666 # kill server relative pids clearing them in %run hash
3669 foreach my $server (@killservers) {
3671 $pidlist .= "$run{$server} ";
3674 $runcert{$server} = 0 if($runcert{$server});
3676 killpid($verbose, $pidlist);
3678 # cleanup server pid files
3680 foreach my $server (@killservers) {
3681 my $pidfile = $serverpidfile{$server};
3682 my $pid = processexists($pidfile);
3684 logmsg "Warning: $server server unexpectedly alive\n";
3685 killpid($verbose, $pid);
3687 unlink($pidfile) if(-f $pidfile);
3691 # remove the test server commands file after each test
3692 unlink($FTPDCMD) if(-f $FTPDCMD);
3694 # run the postcheck command
3695 my @postcheck= getpart("client", "postcheck");
3697 $cmd = $postcheck[0];
3701 logmsg "postcheck $cmd\n" if($verbose);
3702 my $rc = runclient("$cmd");
3703 # Must run the postcheck command in torture mode in order
3704 # to clean up, but the result can't be relied upon.
3705 if($rc != 0 && !$torture) {
3706 logmsg " postcheck FAILED\n";
3707 # timestamp test result verification end
3708 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3714 # restore environment variables that were modified
3716 foreach my $var (keys %oldenv) {
3717 if($oldenv{$var} eq 'notset') {
3718 delete $ENV{$var} if($ENV{$var});
3721 $ENV{$var} = "$oldenv{$var}";
3726 # Skip all the verification on torture tests
3728 if(!$cmdres && !$keepoutfiles) {
3731 # timestamp test result verification end
3732 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3736 my @err = getpart("verify", "errorcode");
3737 my $errorcode = $err[0] || "0";
3742 # verify redirected stdout
3743 my @actual = loadarray($STDOUT);
3745 # variable-replace in the stdout we have from the test case file
3746 @validstdout = fixarray(@validstdout);
3748 # get all attributes
3749 my %hash = getpartattr("verify", "stdout");
3751 # get the mode attribute
3752 my $filemode=$hash{'mode'};
3753 if($filemode && ($filemode eq "text") && $has_textaware) {
3754 # text mode when running on windows: fix line endings
3755 map s/\r\n/\n/g, @validstdout;
3756 map s/\n/\r\n/g, @validstdout;
3759 if($hash{'nonewline'}) {
3760 # Yes, we must cut off the final newline from the final line
3761 # of the protocol data
3762 chomp($validstdout[$#validstdout]);
3765 $res = compare($testnum, $testname, "stdout", \@actual, \@validstdout);
3772 $ok .= "-"; # stdout not checked
3776 # Verify the sent request
3777 my @out = loadarray($SERVERIN);
3779 # what to cut off from the live protocol sent by curl
3780 my @strip = getpart("verify", "strip");
3782 my @protstrip=@protocol;
3784 # check if there's any attributes on the verify/protocol section
3785 my %hash = getpartattr("verify", "protocol");
3787 if($hash{'nonewline'}) {
3788 # Yes, we must cut off the final newline from the final line
3789 # of the protocol data
3790 chomp($protstrip[$#protstrip]);
3794 # strip off all lines that match the patterns from both arrays
3796 @out = striparray( $_, \@out);
3797 @protstrip= striparray( $_, \@protstrip);
3800 # what parts to cut off from the protocol
3801 my @strippart = getpart("verify", "strippart");
3803 for $strip (@strippart) {
3810 $res = compare($testnum, $testname, "protocol", \@out, \@protstrip);
3819 $ok .= "-"; # protocol not checked
3822 if(!$replyattr{'nocheck'} && (@reply || $replyattr{'sendzero'})) {
3823 # verify the received data
3824 my @out = loadarray($CURLOUT);
3825 # get the mode attribute
3826 my $filemode=$replyattr{'mode'};
3827 if($filemode && ($filemode eq "text") && $has_textaware) {
3828 # text mode when running on windows: fix line endings
3829 map s/\r\n/\n/g, @reply;
3830 map s/\n/\r\n/g, @reply;
3833 $res = compare($testnum, $testname, "data", \@out, \@reply);
3840 $ok .= "-"; # data not checked
3844 # verify uploaded data
3845 my @out = loadarray("$LOGDIR/upload.$testnum");
3846 $res = compare($testnum, $testname, "upload", \@out, \@upload);
3853 $ok .= "-"; # upload not checked
3857 # Verify the sent proxy request
3858 my @out = loadarray($PROXYIN);
3860 # what to cut off from the live protocol sent by curl, we use the
3861 # same rules as for <protocol>
3862 my @strip = getpart("verify", "strip");
3864 my @protstrip=@proxyprot;
3866 # check if there's any attributes on the verify/protocol section
3867 my %hash = getpartattr("verify", "proxy");
3869 if($hash{'nonewline'}) {
3870 # Yes, we must cut off the final newline from the final line
3871 # of the protocol data
3872 chomp($protstrip[$#protstrip]);
3876 # strip off all lines that match the patterns from both arrays
3878 @out = striparray( $_, \@out);
3879 @protstrip= striparray( $_, \@protstrip);
3882 # what parts to cut off from the protocol
3883 my @strippart = getpart("verify", "strippart");
3885 for $strip (@strippart) {
3892 $res = compare($testnum, $testname, "proxy", \@out, \@protstrip);
3901 $ok .= "-"; # protocol not checked
3905 for my $partsuffix (('', '1', '2', '3', '4')) {
3906 my @outfile=getpart("verify", "file".$partsuffix);
3907 if(@outfile || partexists("verify", "file".$partsuffix) ) {
3908 # we're supposed to verify a dynamically generated file!
3909 my %hash = getpartattr("verify", "file".$partsuffix);
3911 my $filename=$hash{'name'};
3913 logmsg "ERROR: section verify=>file$partsuffix ".
3914 "has no name attribute\n";
3915 stopservers($verbose);
3916 # timestamp test result verification end
3917 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3920 my @generated=loadarray($filename);
3922 # what parts to cut off from the file
3923 my @stripfile = getpart("verify", "stripfile".$partsuffix);
3925 my $filemode=$hash{'mode'};
3926 if($filemode && ($filemode eq "text") && $has_textaware) {
3927 # text mode when running on windows: fix line endings
3928 map s/\r\n/\n/g, @outfile;
3929 map s/\n/\r\n/g, @outfile;
3933 for $strip (@stripfile) {
3942 # this is to get rid of array entries that vanished (zero
3943 # length) because of replacements
3944 @generated = @newgen;
3947 @outfile = fixarray(@outfile);
3949 $res = compare($testnum, $testname, "output ($filename)",
3950 \@generated, \@outfile);
3955 $outputok = 1; # output checked
3958 $ok .= ($outputok) ? "o" : "-"; # output checked or not
3960 # accept multiple comma-separated error codes
3961 my @splerr = split(/ *, */, $errorcode);
3963 foreach my $e (@splerr) {
3976 logmsg sprintf("\n%s returned $cmdres, when expecting %s\n",
3977 (!$tool)?"curl":$tool, $errorcode);
3979 logmsg " exit FAILED\n";
3980 # timestamp test result verification end
3981 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3985 if($has_memory_tracking) {
3987 logmsg "\n** ALERT! memory tracking with no output file?\n"
3988 if(!$cmdtype eq "perl");
3991 my @memdata=`$memanalyze $memdump`;
3995 # well it could be other memory problems as well, but
3996 # we call it leak for short here
4001 logmsg "\n** MEMORY FAILURE\n";
4003 # timestamp test result verification end
4004 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
4013 $ok .= "-"; # memory not checked
4018 unless(opendir(DIR, "$LOGDIR")) {
4019 logmsg "ERROR: unable to read $LOGDIR\n";
4020 # timestamp test result verification end
4021 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
4024 my @files = readdir(DIR);
4027 foreach my $file (@files) {
4028 if($file =~ /^valgrind$testnum(\..*|)$/) {
4034 logmsg "ERROR: valgrind log file missing for test $testnum\n";
4035 # timestamp test result verification end
4036 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
4039 my @e = valgrindparse($srcdir, $feature{'SSL'}, "$LOGDIR/$vgfile");
4041 if($automakestyle) {
4042 logmsg "FAIL: $testnum - $testname - valgrind\n";
4045 logmsg " valgrind ERROR ";
4048 # timestamp test result verification end
4049 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
4055 if(!$short && !$disablevalgrind) {
4056 logmsg " valgrind SKIPPED\n";
4058 $ok .= "-"; # skipped
4062 $ok .= "-"; # valgrind not checked
4064 # add 'E' for event-based
4065 $ok .= $evbased ? "E" : "-";
4067 logmsg "$ok " if(!$short);
4069 my $sofar= time()-$start;
4070 my $esttotal = $sofar/$count * $total;
4071 my $estleft = $esttotal - $sofar;
4072 my $left=sprintf("remaining: %02d:%02d",
4076 if(!$automakestyle) {
4077 logmsg sprintf("OK (%-3d out of %-3d, %s)\n", $count, $total, $left);
4080 logmsg "PASS: $testnum - $testname\n";
4083 # the test succeeded, remove all log files
4084 if(!$keepoutfiles) {
4088 # timestamp test result verification end
4089 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
4094 #######################################################################
4095 # Stop all running test servers
4098 my $verbose = $_[0];
4100 # kill sockfilter processes for all pingpong servers
4102 killallsockfilters($verbose);
4104 # kill all server pids from %run hash clearing them
4107 foreach my $server (keys %run) {
4111 my $pids = $run{$server};
4112 foreach my $pid (split(' ', $pids)) {
4114 logmsg sprintf("* kill pid for %s => %d\n",
4120 $pidlist .= "$run{$server} ";
4123 $runcert{$server} = 0 if($runcert{$server});
4125 killpid($verbose, $pidlist);
4127 # cleanup all server pid files
4129 foreach my $server (keys %serverpidfile) {
4130 my $pidfile = $serverpidfile{$server};
4131 my $pid = processexists($pidfile);
4133 logmsg "Warning: $server server unexpectedly alive\n";
4134 killpid($verbose, $pid);
4136 unlink($pidfile) if(-f $pidfile);
4140 #######################################################################
4141 # startservers() starts all the named servers
4143 # Returns: string with error reason or blank for success
4149 my (@whatlist) = split(/\s+/,$_);
4150 my $what = lc($whatlist[0]);
4151 $what =~ s/[^a-z0-9-]//g;
4154 if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
4155 $certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem';
4158 if(($what eq "pop3") ||
4160 ($what eq "imap") ||
4161 ($what eq "smtp")) {
4162 if($torture && $run{$what} &&
4163 !responsive_pingpong_server($what, "", $verbose)) {
4167 ($pid, $pid2) = runpingpongserver($what, "", $verbose);
4169 return "failed starting ". uc($what) ." server";
4171 printf ("* pid $what => %d %d\n", $pid, $pid2) if($verbose);
4172 $run{$what}="$pid $pid2";
4175 elsif($what eq "ftp2") {
4176 if($torture && $run{'ftp2'} &&
4177 !responsive_pingpong_server("ftp", "2", $verbose)) {
4181 ($pid, $pid2) = runpingpongserver("ftp", "2", $verbose);
4183 return "failed starting FTP2 server";
4185 printf ("* pid ftp2 => %d %d\n", $pid, $pid2) if($verbose);
4186 $run{'ftp2'}="$pid $pid2";
4189 elsif($what eq "ftp-ipv6") {
4190 if($torture && $run{'ftp-ipv6'} &&
4191 !responsive_pingpong_server("ftp", "", $verbose, "ipv6")) {
4192 stopserver('ftp-ipv6');
4194 if(!$run{'ftp-ipv6'}) {
4195 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose, "ipv6");
4197 return "failed starting FTP-IPv6 server";
4199 logmsg sprintf("* pid ftp-ipv6 => %d %d\n", $pid,
4200 $pid2) if($verbose);
4201 $run{'ftp-ipv6'}="$pid $pid2";
4204 elsif($what eq "gopher") {
4205 if($torture && $run{'gopher'} &&
4206 !responsive_http_server("gopher", $verbose, 0, $GOPHERPORT)) {
4207 stopserver('gopher');
4209 if(!$run{'gopher'}) {
4210 ($pid, $pid2) = runhttpserver("gopher", $verbose, 0,
4213 return "failed starting GOPHER server";
4215 logmsg sprintf ("* pid gopher => %d %d\n", $pid, $pid2)
4217 $run{'gopher'}="$pid $pid2";
4220 elsif($what eq "gopher-ipv6") {
4221 if($torture && $run{'gopher-ipv6'} &&
4222 !responsive_http_server("gopher", $verbose, "ipv6",
4224 stopserver('gopher-ipv6');
4226 if(!$run{'gopher-ipv6'}) {
4227 ($pid, $pid2) = runhttpserver("gopher", $verbose, "ipv6",
4230 return "failed starting GOPHER-IPv6 server";
4232 logmsg sprintf("* pid gopher-ipv6 => %d %d\n", $pid,
4233 $pid2) if($verbose);
4234 $run{'gopher-ipv6'}="$pid $pid2";
4237 elsif($what eq "http") {
4238 if($torture && $run{'http'} &&
4239 !responsive_http_server("http", $verbose, 0, $HTTPPORT)) {
4243 ($pid, $pid2) = runhttpserver("http", $verbose, 0,
4246 return "failed starting HTTP server";
4248 logmsg sprintf ("* pid http => %d %d\n", $pid, $pid2)
4250 $run{'http'}="$pid $pid2";
4253 elsif($what eq "http-proxy") {
4254 if($torture && $run{'http-proxy'} &&
4255 !responsive_http_server("http", $verbose, "proxy",
4257 stopserver('http-proxy');
4259 if(!$run{'http-proxy'}) {
4260 ($pid, $pid2) = runhttpserver("http", $verbose, "proxy",
4263 return "failed starting HTTP-proxy server";
4265 logmsg sprintf ("* pid http-proxy => %d %d\n", $pid, $pid2)
4267 $run{'http-proxy'}="$pid $pid2";
4270 elsif($what eq "http-ipv6") {
4271 if($torture && $run{'http-ipv6'} &&
4272 !responsive_http_server("http", $verbose, "ipv6", $HTTP6PORT)) {
4273 stopserver('http-ipv6');
4275 if(!$run{'http-ipv6'}) {
4276 ($pid, $pid2) = runhttpserver("http", $verbose, "ipv6",
4279 return "failed starting HTTP-IPv6 server";
4281 logmsg sprintf("* pid http-ipv6 => %d %d\n", $pid, $pid2)
4283 $run{'http-ipv6'}="$pid $pid2";
4286 elsif($what eq "http-pipe") {
4287 if($torture && $run{'http-pipe'} &&
4288 !responsive_http_server("http", $verbose, "pipe",
4290 stopserver('http-pipe');
4292 if(!$run{'http-pipe'}) {
4293 ($pid, $pid2) = runhttpserver("http", $verbose, "pipe",
4296 return "failed starting HTTP-pipe server";
4298 logmsg sprintf ("* pid http-pipe => %d %d\n", $pid, $pid2)
4300 $run{'http-pipe'}="$pid $pid2";
4303 elsif($what eq "rtsp") {
4304 if($torture && $run{'rtsp'} &&
4305 !responsive_rtsp_server($verbose)) {
4309 ($pid, $pid2) = runrtspserver($verbose);
4311 return "failed starting RTSP server";
4313 printf ("* pid rtsp => %d %d\n", $pid, $pid2) if($verbose);
4314 $run{'rtsp'}="$pid $pid2";
4317 elsif($what eq "rtsp-ipv6") {
4318 if($torture && $run{'rtsp-ipv6'} &&
4319 !responsive_rtsp_server($verbose, "ipv6")) {
4320 stopserver('rtsp-ipv6');
4322 if(!$run{'rtsp-ipv6'}) {
4323 ($pid, $pid2) = runrtspserver($verbose, "ipv6");
4325 return "failed starting RTSP-IPv6 server";
4327 logmsg sprintf("* pid rtsp-ipv6 => %d %d\n", $pid, $pid2)
4329 $run{'rtsp-ipv6'}="$pid $pid2";
4332 elsif($what eq "ftps") {
4334 # we can't run ftps tests without stunnel
4335 return "no stunnel";
4338 # we can't run ftps tests if libcurl is SSL-less
4339 return "curl lacks SSL support";
4341 if($runcert{'ftps'} && ($runcert{'ftps'} ne $certfile)) {
4342 # stop server when running and using a different cert
4345 if($torture && $run{'ftp'} &&
4346 !responsive_pingpong_server("ftp", "", $verbose)) {
4350 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose);
4352 return "failed starting FTP server";
4354 printf ("* pid ftp => %d %d\n", $pid, $pid2) if($verbose);
4355 $run{'ftp'}="$pid $pid2";
4358 ($pid, $pid2) = runftpsserver($verbose, "", $certfile);
4360 return "failed starting FTPS server (stunnel)";
4362 logmsg sprintf("* pid ftps => %d %d\n", $pid, $pid2)
4364 $run{'ftps'}="$pid $pid2";
4367 elsif($what eq "file") {
4368 # we support it but have no server!
4370 elsif($what eq "https") {
4372 # we can't run https tests without stunnel
4373 return "no stunnel";
4376 # we can't run https tests if libcurl is SSL-less
4377 return "curl lacks SSL support";
4379 if($runcert{'https'} && ($runcert{'https'} ne $certfile)) {
4380 # stop server when running and using a different cert
4381 stopserver('https');
4383 if($torture && $run{'http'} &&
4384 !responsive_http_server("http", $verbose, 0, $HTTPPORT)) {
4388 ($pid, $pid2) = runhttpserver("http", $verbose, 0,
4391 return "failed starting HTTP server";
4393 printf ("* pid http => %d %d\n", $pid, $pid2) if($verbose);
4394 $run{'http'}="$pid $pid2";
4396 if(!$run{'https'}) {
4397 ($pid, $pid2) = runhttpsserver($verbose, "", $certfile);
4399 return "failed starting HTTPS server (stunnel)";
4401 logmsg sprintf("* pid https => %d %d\n", $pid, $pid2)
4403 $run{'https'}="$pid $pid2";
4406 elsif($what eq "httptls") {
4408 # for now, we can't run http TLS-EXT tests without gnutls-serv
4409 return "no gnutls-serv";
4411 if($torture && $run{'httptls'} &&
4412 !responsive_httptls_server($verbose, "IPv4")) {
4413 stopserver('httptls');
4415 if(!$run{'httptls'}) {
4416 ($pid, $pid2) = runhttptlsserver($verbose, "IPv4");
4418 return "failed starting HTTPTLS server (gnutls-serv)";
4420 logmsg sprintf("* pid httptls => %d %d\n", $pid, $pid2)
4422 $run{'httptls'}="$pid $pid2";
4425 elsif($what eq "httptls-ipv6") {
4427 # for now, we can't run http TLS-EXT tests without gnutls-serv
4428 return "no gnutls-serv";
4430 if($torture && $run{'httptls-ipv6'} &&
4431 !responsive_httptls_server($verbose, "ipv6")) {
4432 stopserver('httptls-ipv6');
4434 if(!$run{'httptls-ipv6'}) {
4435 ($pid, $pid2) = runhttptlsserver($verbose, "ipv6");
4437 return "failed starting HTTPTLS-IPv6 server (gnutls-serv)";
4439 logmsg sprintf("* pid httptls-ipv6 => %d %d\n", $pid, $pid2)
4441 $run{'httptls-ipv6'}="$pid $pid2";
4444 elsif($what eq "tftp") {
4445 if($torture && $run{'tftp'} &&
4446 !responsive_tftp_server("", $verbose)) {
4450 ($pid, $pid2) = runtftpserver("", $verbose);
4452 return "failed starting TFTP server";
4454 printf ("* pid tftp => %d %d\n", $pid, $pid2) if($verbose);
4455 $run{'tftp'}="$pid $pid2";
4458 elsif($what eq "tftp-ipv6") {
4459 if($torture && $run{'tftp-ipv6'} &&
4460 !responsive_tftp_server("", $verbose, "ipv6")) {
4461 stopserver('tftp-ipv6');
4463 if(!$run{'tftp-ipv6'}) {
4464 ($pid, $pid2) = runtftpserver("", $verbose, "ipv6");
4466 return "failed starting TFTP-IPv6 server";
4468 printf("* pid tftp-ipv6 => %d %d\n", $pid, $pid2) if($verbose);
4469 $run{'tftp-ipv6'}="$pid $pid2";
4472 elsif($what eq "sftp" || $what eq "scp" || $what eq "socks4" || $what eq "socks5" ) {
4474 ($pid, $pid2) = runsshserver("", $verbose);
4476 return "failed starting SSH server";
4478 printf ("* pid ssh => %d %d\n", $pid, $pid2) if($verbose);
4479 $run{'ssh'}="$pid $pid2";
4481 if($what eq "socks4" || $what eq "socks5") {
4482 if(!$run{'socks'}) {
4483 ($pid, $pid2) = runsocksserver("", $verbose);
4485 return "failed starting socks server";
4487 printf ("* pid socks => %d %d\n", $pid, $pid2) if($verbose);
4488 $run{'socks'}="$pid $pid2";
4491 if($what eq "socks5") {
4493 # Not an OpenSSH or SunSSH ssh daemon
4494 logmsg "Not OpenSSH or SunSSH; socks5 tests need at least OpenSSH 3.7\n";
4495 return "failed starting socks5 server";
4497 elsif(($sshdid =~ /OpenSSH/) && ($sshdvernum < 370)) {
4498 # Need OpenSSH 3.7 for socks5 - http://www.openssh.com/txt/release-3.7
4499 logmsg "$sshdverstr insufficient; socks5 tests need at least OpenSSH 3.7\n";
4500 return "failed starting socks5 server";
4502 elsif(($sshdid =~ /SunSSH/) && ($sshdvernum < 100)) {
4503 # Need SunSSH 1.0 for socks5
4504 logmsg "$sshdverstr insufficient; socks5 tests need at least SunSSH 1.0\n";
4505 return "failed starting socks5 server";
4509 elsif($what eq "http-unix") {
4510 if($torture && $run{'http-unix'} &&
4511 !responsive_http_server("http", $verbose, "unix", $HTTPUNIXPATH)) {
4512 stopserver('http-unix');
4514 if(!$run{'http-unix'}) {
4515 ($pid, $pid2) = runhttpserver("http", $verbose, "unix",
4518 return "failed starting HTTP-unix server";
4520 logmsg sprintf("* pid http-unix => %d %d\n", $pid, $pid2)
4522 $run{'http-unix'}="$pid $pid2";
4525 elsif($what eq "none") {
4526 logmsg "* starts no server\n" if ($verbose);
4529 warn "we don't support a server for $what";
4530 return "no server for $what";
4536 ##############################################################################
4537 # This function makes sure the right set of server is running for the
4538 # specified test case. This is a useful design when we run single tests as not
4539 # all servers need to run then!
4541 # Returns: a string, blank if everything is fine or a reason why it failed
4546 my @what = getpart("client", "server");
4549 warn "Test case $testnum has no server(s) specified";
4550 return "no server specified";
4553 for(my $i = scalar(@what) - 1; $i >= 0; $i--) {
4554 my $srvrline = $what[$i];
4555 chomp $srvrline if($srvrline);
4556 if($srvrline =~ /^(\S+)((\s*)(.*))/) {
4557 my $server = "${1}";
4558 my $lnrest = "${2}";
4560 if($server =~ /^(httptls)(\+)(ext|srp)(\d*)(-ipv6|)$/) {
4561 $server = "${1}${4}${5}";
4562 $tlsext = uc("TLS-${3}");
4564 if(! grep /^\Q$server\E$/, @protocols) {
4565 if(substr($server,0,5) ne "socks") {
4567 return "curl lacks $tlsext support";
4570 return "curl lacks $server server support";
4574 $what[$i] = "$server$lnrest" if($tlsext);
4578 return &startservers(@what);
4581 #######################################################################
4582 # runtimestats displays test-suite run time statistics
4585 my $lasttest = $_[0];
4587 return if(not $timestats);
4589 logmsg "\nTest suite total running time breakdown per task...\n\n";
4597 my $timesrvrtot = 0.0;
4598 my $timepreptot = 0.0;
4599 my $timetooltot = 0.0;
4600 my $timelocktot = 0.0;
4601 my $timevrfytot = 0.0;
4602 my $timetesttot = 0.0;
4605 for my $testnum (1 .. $lasttest) {
4606 if($timesrvrini{$testnum}) {
4607 $timesrvrtot += $timesrvrend{$testnum} - $timesrvrini{$testnum};
4609 (($timetoolini{$testnum} - $timeprepini{$testnum}) -
4610 ($timesrvrend{$testnum} - $timesrvrini{$testnum}));
4611 $timetooltot += $timetoolend{$testnum} - $timetoolini{$testnum};
4612 $timelocktot += $timesrvrlog{$testnum} - $timetoolend{$testnum};
4613 $timevrfytot += $timevrfyend{$testnum} - $timesrvrlog{$testnum};
4614 $timetesttot += $timevrfyend{$testnum} - $timeprepini{$testnum};
4615 push @timesrvr, sprintf("%06.3f %04d",
4616 $timesrvrend{$testnum} - $timesrvrini{$testnum}, $testnum);
4617 push @timeprep, sprintf("%06.3f %04d",
4618 ($timetoolini{$testnum} - $timeprepini{$testnum}) -
4619 ($timesrvrend{$testnum} - $timesrvrini{$testnum}), $testnum);
4620 push @timetool, sprintf("%06.3f %04d",
4621 $timetoolend{$testnum} - $timetoolini{$testnum}, $testnum);
4622 push @timelock, sprintf("%06.3f %04d",
4623 $timesrvrlog{$testnum} - $timetoolend{$testnum}, $testnum);
4624 push @timevrfy, sprintf("%06.3f %04d",
4625 $timevrfyend{$testnum} - $timesrvrlog{$testnum}, $testnum);
4626 push @timetest, sprintf("%06.3f %04d",
4627 $timevrfyend{$testnum} - $timeprepini{$testnum}, $testnum);
4632 no warnings 'numeric';
4633 @timesrvr = sort { $b <=> $a } @timesrvr;
4634 @timeprep = sort { $b <=> $a } @timeprep;
4635 @timetool = sort { $b <=> $a } @timetool;
4636 @timelock = sort { $b <=> $a } @timelock;
4637 @timevrfy = sort { $b <=> $a } @timevrfy;
4638 @timetest = sort { $b <=> $a } @timetest;
4641 logmsg "Spent ". sprintf("%08.3f ", $timesrvrtot) .
4642 "seconds starting and verifying test harness servers.\n";
4643 logmsg "Spent ". sprintf("%08.3f ", $timepreptot) .
4644 "seconds reading definitions and doing test preparations.\n";
4645 logmsg "Spent ". sprintf("%08.3f ", $timetooltot) .
4646 "seconds actually running test tools.\n";
4647 logmsg "Spent ". sprintf("%08.3f ", $timelocktot) .
4648 "seconds awaiting server logs lock removal.\n";
4649 logmsg "Spent ". sprintf("%08.3f ", $timevrfytot) .
4650 "seconds verifying test results.\n";
4651 logmsg "Spent ". sprintf("%08.3f ", $timetesttot) .
4652 "seconds doing all of the above.\n";
4655 logmsg "\nTest server starting and verification time per test ".
4656 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4657 logmsg "-time- test\n";
4658 logmsg "------ ----\n";
4659 foreach my $txt (@timesrvr) {
4660 last if((not $fullstats) && (not $counter--));
4665 logmsg "\nTest definition reading and preparation time per test ".
4666 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4667 logmsg "-time- test\n";
4668 logmsg "------ ----\n";
4669 foreach my $txt (@timeprep) {
4670 last if((not $fullstats) && (not $counter--));
4675 logmsg "\nTest tool execution time per test ".
4676 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4677 logmsg "-time- test\n";
4678 logmsg "------ ----\n";
4679 foreach my $txt (@timetool) {
4680 last if((not $fullstats) && (not $counter--));
4685 logmsg "\nTest server logs lock removal time per test ".
4686 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4687 logmsg "-time- test\n";
4688 logmsg "------ ----\n";
4689 foreach my $txt (@timelock) {
4690 last if((not $fullstats) && (not $counter--));
4695 logmsg "\nTest results verification time per test ".
4696 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4697 logmsg "-time- test\n";
4698 logmsg "------ ----\n";
4699 foreach my $txt (@timevrfy) {
4700 last if((not $fullstats) && (not $counter--));
4705 logmsg "\nTotal time per test ".
4706 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4707 logmsg "-time- test\n";
4708 logmsg "------ ----\n";
4709 foreach my $txt (@timetest) {
4710 last if((not $fullstats) && (not $counter--));
4717 #######################################################################
4718 # Check options to this test program
4725 if ($ARGV[0] eq "-v") {
4729 elsif($ARGV[0] =~ /^-b(.*)/) {
4731 if($portno =~ s/(\d+)$//) {
4735 elsif ($ARGV[0] eq "-c") {
4736 # use this path to curl instead of default
4737 $DBGCURL=$CURL="\"$ARGV[1]\"";
4740 elsif ($ARGV[0] eq "-vc") {
4741 # use this path to a curl used to verify servers
4743 # Particularly useful when you introduce a crashing bug somewhere in
4744 # the development version as then it won't be able to run any tests
4745 # since it can't verify the servers!
4750 elsif ($ARGV[0] eq "-d") {
4751 # have the servers display protocol output
4754 elsif ($ARGV[0] eq "-g") {
4755 # run this test with gdb
4758 elsif ($ARGV[0] eq "-gw") {
4759 # run this test with windowed gdb
4763 elsif($ARGV[0] eq "-s") {
4767 elsif($ARGV[0] eq "-am") {
4768 # automake-style output
4772 elsif($ARGV[0] eq "-n") {
4776 elsif($ARGV[0] =~ /^-t(.*)/) {
4781 if($xtra =~ s/(\d+)$//) {
4784 # we undef valgrind to make this fly in comparison
4787 elsif($ARGV[0] eq "-a") {
4788 # continue anyway, even if a test fail
4791 elsif($ARGV[0] eq "-e") {
4792 # run the tests cases event based if possible
4795 elsif($ARGV[0] eq "-p") {
4798 elsif($ARGV[0] eq "-l") {
4799 # lists the test case names only
4802 elsif($ARGV[0] eq "-k") {
4803 # keep stdout and stderr files after tests
4806 elsif($ARGV[0] eq "-r") {
4807 # run time statistics needs Time::HiRes
4808 if($Time::HiRes::VERSION) {
4809 keys(%timeprepini) = 1000;
4810 keys(%timesrvrini) = 1000;
4811 keys(%timesrvrend) = 1000;
4812 keys(%timetoolini) = 1000;
4813 keys(%timetoolend) = 1000;
4814 keys(%timesrvrlog) = 1000;
4815 keys(%timevrfyend) = 1000;
4820 elsif($ARGV[0] eq "-rf") {
4821 # run time statistics needs Time::HiRes
4822 if($Time::HiRes::VERSION) {
4823 keys(%timeprepini) = 1000;
4824 keys(%timesrvrini) = 1000;
4825 keys(%timesrvrend) = 1000;
4826 keys(%timetoolini) = 1000;
4827 keys(%timetoolend) = 1000;
4828 keys(%timesrvrlog) = 1000;
4829 keys(%timevrfyend) = 1000;
4834 elsif(($ARGV[0] eq "-h") || ($ARGV[0] eq "--help")) {
4837 Usage: runtests.pl [options] [test selection(s)]
4838 -a continue even if a test fails
4839 -bN use base port number N for test servers (default $base)
4840 -c path use this curl executable
4841 -d display server debug info
4842 -g run the test case with gdb
4843 -gw run the test case with gdb as a windowed application
4845 -k keep stdout and stderr files present after tests
4846 -l list all test case names/descriptions
4848 -p print log file contents when a test fails
4849 -r run time statistics
4850 -rf full run time statistics
4852 -am automake style output PASS/FAIL: [number] [name]
4853 -t[N] torture (simulate memory alloc failures); N means fail Nth alloc
4855 -vc path use this curl only to verify the existing servers
4856 [num] like "5 6 9" or " 5 to 22 " to run those tests only
4857 [!num] like "!5 !6 !9" to disable those tests
4858 [keyword] like "IPv6" to select only tests containing the key word
4859 [!keyword] like "!cookies" to disable any tests containing the key word
4864 elsif($ARGV[0] =~ /^(\d+)/) {
4867 for($fromnum .. $number) {
4876 elsif($ARGV[0] =~ /^to$/i) {
4877 $fromnum = $number+1;
4879 elsif($ARGV[0] =~ /^!(\d+)/) {
4883 elsif($ARGV[0] =~ /^!(.+)/) {
4884 $disabled_keywords{$1}=$1;
4886 elsif($ARGV[0] =~ /^([-[{a-zA-Z].*)/) {
4887 $enabled_keywords{$1}=$1;
4890 print "Unknown option: $ARGV[0]\n";
4896 if(@testthis && ($testthis[0] ne "")) {
4897 $TESTCASES=join(" ", @testthis);
4901 # we have found valgrind on the host, use it
4903 # verify that we can invoke it fine
4904 my $code = runclient("valgrind >/dev/null 2>&1");
4906 if(($code>>8) != 1) {
4907 #logmsg "Valgrind failure, disable it\n";
4911 # since valgrind 2.1.x, '--tool' option is mandatory
4912 # use it, if it is supported by the version installed on the system
4913 runclient("valgrind --help 2>&1 | grep -- --tool > /dev/null 2>&1");
4915 $valgrind_tool="--tool=memcheck";
4920 # A shell script. This is typically when built with libtool,
4921 $valgrind="../libtool --mode=execute $valgrind";
4925 # valgrind 3 renamed the --logfile option to --log-file!!!
4926 my $ver=join(' ', runclientoutput("valgrind --version"));
4927 # cut off all but digits and dots
4928 $ver =~ s/[^0-9.]//g;
4930 if($ver =~ /^(\d+)/) {
4933 $valgrind_logfile="--log-file";
4940 # open the executable curl and read the first 4 bytes of it
4941 open(CHECK, "<$CURL");
4943 sysread CHECK, $c, 4;
4946 # A shell script. This is typically when built with libtool,
4948 $gdb = "../libtool --mode=execute gdb";
4952 $HTTPPORT = $base++; # HTTP server port
4953 $HTTPSPORT = $base++; # HTTPS (stunnel) server port
4954 $FTPPORT = $base++; # FTP server port
4955 $FTPSPORT = $base++; # FTPS (stunnel) server port
4956 $HTTP6PORT = $base++; # HTTP IPv6 server port
4957 $FTP2PORT = $base++; # FTP server 2 port
4958 $FTP6PORT = $base++; # FTP IPv6 port
4959 $TFTPPORT = $base++; # TFTP (UDP) port
4960 $TFTP6PORT = $base++; # TFTP IPv6 (UDP) port
4961 $SSHPORT = $base++; # SSH (SCP/SFTP) port
4962 $SOCKSPORT = $base++; # SOCKS port
4963 $POP3PORT = $base++; # POP3 server port
4964 $POP36PORT = $base++; # POP3 IPv6 server port
4965 $IMAPPORT = $base++; # IMAP server port
4966 $IMAP6PORT = $base++; # IMAP IPv6 server port
4967 $SMTPPORT = $base++; # SMTP server port
4968 $SMTP6PORT = $base++; # SMTP IPv6 server port
4969 $RTSPPORT = $base++; # RTSP server port
4970 $RTSP6PORT = $base++; # RTSP IPv6 server port
4971 $GOPHERPORT = $base++; # Gopher IPv4 server port
4972 $GOPHER6PORT = $base++; # Gopher IPv6 server port
4973 $HTTPTLSPORT = $base++; # HTTP TLS (non-stunnel) server port
4974 $HTTPTLS6PORT = $base++; # HTTP TLS (non-stunnel) IPv6 server port
4975 $HTTPPROXYPORT = $base++; # HTTP proxy port, when using CONNECT
4976 $HTTPPIPEPORT = $base++; # HTTP pipelining port
4977 $HTTPUNIXPATH = 'http.sock'; # HTTP server Unix domain socket path
4979 #######################################################################
4980 # clear and create logging directory:
4984 mkdir($LOGDIR, 0777);
4986 #######################################################################
4987 # initialize some variables
4991 init_serverpidfile_hash();
4993 #######################################################################
4994 # Output curl version and host info being tested
5001 #######################################################################
5002 # Fetch all disabled tests, if there are any
5008 if(open(D, "<$file")) {
5015 $disabled{$1}=$1; # disable this test number
5022 # globally disabled tests
5023 disabledtests("$TESTDIR/DISABLED");
5025 # locally disabled tests, ignored by git etc
5026 disabledtests("$TESTDIR/DISABLED.local");
5028 #######################################################################
5029 # If 'all' tests are requested, find out all test numbers
5032 if ( $TESTCASES eq "all") {
5033 # Get all commands and find out their test numbers
5034 opendir(DIR, $TESTDIR) || die "can't opendir $TESTDIR: $!";
5035 my @cmds = grep { /^test([0-9]+)$/ && -f "$TESTDIR/$_" } readdir(DIR);
5038 $TESTCASES=""; # start with no test cases
5040 # cut off everything but the digits
5042 $_ =~ s/[a-z\/\.]*//g;
5044 # sort the numbers from low to high
5045 foreach my $n (sort { $a <=> $b } @cmds) {
5047 # skip disabled test cases
5048 my $why = "configured as DISABLED";
5051 $teststat[$n]=$why; # store reason for this test case
5054 $TESTCASES .= " $n";
5060 if (-e "$TESTDIR/test$_") {
5063 } split(" ", $TESTCASES);
5064 if($verified eq "") {
5065 print "No existing test cases were specified\n";
5068 $TESTCASES = $verified;
5071 #######################################################################
5072 # Start the command line log
5074 open(CMDLOG, ">$CURLLOG") ||
5075 logmsg "can't log command lines to $CURLLOG\n";
5077 #######################################################################
5079 # Display the contents of the given file. Line endings are canonicalized
5080 # and excessively long files are elided
5081 sub displaylogcontent {
5083 if(open(SINGLE, "<$file")) {
5087 while(my $string = <SINGLE>) {
5088 $string =~ s/\r\n/\n/g;
5089 $string =~ s/[\r\f\032]/\n/g;
5090 $string .= "\n" unless ($string =~ /\n$/);
5092 for my $line (split("\n", $string)) {
5093 $line =~ s/\s*\!$//;
5095 push @tail, " $line\n";
5100 $truncate = $linecount > 1000;
5106 my $tailtotal = scalar @tail;
5107 if($tailtotal > $tailshow) {
5108 $tailskip = $tailtotal - $tailshow;
5109 logmsg "=== File too long: $tailskip lines omitted here\n";
5111 for($tailskip .. $tailtotal-1) {
5121 opendir(DIR, "$LOGDIR") ||
5122 die "can't open dir: $!";
5123 my @logs = readdir(DIR);
5126 logmsg "== Contents of files in the $LOGDIR/ dir after test $testnum\n";
5127 foreach my $log (sort @logs) {
5128 if($log =~ /\.(\.|)$/) {
5129 next; # skip "." and ".."
5131 if($log =~ /^\.nfs/) {
5134 if(($log eq "memdump") || ($log eq "core")) {
5135 next; # skip "memdump" and "core"
5137 if((-d "$LOGDIR/$log") || (! -s "$LOGDIR/$log")) {
5138 next; # skip directory and empty files
5140 if(($log =~ /^stdout\d+/) && ($log !~ /^stdout$testnum/)) {
5141 next; # skip stdoutNnn of other tests
5143 if(($log =~ /^stderr\d+/) && ($log !~ /^stderr$testnum/)) {
5144 next; # skip stderrNnn of other tests
5146 if(($log =~ /^upload\d+/) && ($log !~ /^upload$testnum/)) {
5147 next; # skip uploadNnn of other tests
5149 if(($log =~ /^curl\d+\.out/) && ($log !~ /^curl$testnum\.out/)) {
5150 next; # skip curlNnn.out of other tests
5152 if(($log =~ /^test\d+\.txt/) && ($log !~ /^test$testnum\.txt/)) {
5153 next; # skip testNnn.txt of other tests
5155 if(($log =~ /^file\d+\.txt/) && ($log !~ /^file$testnum\.txt/)) {
5156 next; # skip fileNnn.txt of other tests
5158 if(($log =~ /^netrc\d+/) && ($log !~ /^netrc$testnum/)) {
5159 next; # skip netrcNnn of other tests
5161 if(($log =~ /^trace\d+/) && ($log !~ /^trace$testnum/)) {
5162 next; # skip traceNnn of other tests
5164 if(($log =~ /^valgrind\d+/) && ($log !~ /^valgrind$testnum(\..*|)$/)) {
5165 next; # skip valgrindNnn of other tests
5167 logmsg "=== Start of file $log\n";
5168 displaylogcontent("$LOGDIR/$log");
5169 logmsg "=== End of file $log\n";
5173 #######################################################################
5174 # The main test-loop
5182 my @at = split(" ", $TESTCASES);
5187 foreach $testnum (@at) {
5189 $lasttest = $testnum if($testnum > $lasttest);
5192 my $error = singletest($run_event_based, $testnum, $count, scalar(@at));
5194 # not a test we can run
5198 $total++; # number of tests we've run
5201 $failed.= "$testnum ";
5203 # display all files in log/ in a nice way
5204 displaylogs($testnum);
5207 # a test failed, abort
5208 logmsg "\n - abort tests\n";
5213 $ok++; # successful test counter
5216 # loop for next test
5219 my $sofar = time() - $start;
5221 #######################################################################
5226 # Tests done, stop the servers
5227 stopservers($verbose);
5229 my $all = $total + $skipped;
5231 runtimestats($lasttest);
5234 logmsg sprintf("TESTDONE: $ok tests out of $total reported OK: %d%%\n",
5238 logmsg "TESTFAIL: These test cases failed: $failed\n";
5242 logmsg "TESTFAIL: No tests were performed\n";
5246 logmsg "TESTDONE: $all tests were considered during ".
5247 sprintf("%.0f", $sofar) ." seconds.\n";
5250 if($skipped && !$short) {
5252 logmsg "TESTINFO: $skipped tests were skipped due to these restraints:\n";
5254 for(keys %skipped) {
5256 printf "TESTINFO: \"%s\" %d times (", $r, $skipped{$_};
5258 # now show all test case numbers that had this reason for being
5262 for(0 .. scalar @teststat) {
5264 if($teststat[$_] && ($teststat[$_] eq $r)) {
5273 logmsg " and ".($c-$max)." more";
5279 if($total && ($ok != $total)) {