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 https://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 $has_ssl; # set if libcurl is built with SSL support
203 my $has_largefile; # 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
227 my $has_psl; # set if libcurl is built with PSL support
229 # this version is decided by the particular nghttp2 library that is being used
232 my $has_openssl; # built with a lib using an OpenSSL-like API
233 my $has_gnutls; # built with GnuTLS
234 my $has_nss; # built with NSS
235 my $has_yassl; # built with yassl
236 my $has_polarssl; # built with polarssl
237 my $has_axtls; # built with axTLS
238 my $has_winssl; # built with WinSSL (Secure Channel aka Schannel)
239 my $has_darwinssl; # built with DarwinSSL (Secure Transport)
240 my $has_boringssl; # built with BoringSSL
241 my $has_libressl; # built with libressl
242 my $has_mbedtls; # built with mbedTLS
244 my $has_sslpinning; # built with a TLS backend that supports pinning
246 my $has_shared = "unknown"; # built shared
248 my $resolver; # name of the resolver backend (for human presentation)
249 my $ssllib; # name of the SSL library we use (for human presentation)
251 my $has_textaware; # set if running on a system that has a text mode concept
252 # on files. Windows for example
254 my @protocols; # array of lowercase supported protocol servers
256 my $skipped=0; # number of tests skipped; reported in main loop
257 my %skipped; # skipped{reason}=counter, reasons for skip
258 my @teststat; # teststat[testnum]=reason, reasons for skip
259 my %disabled_keywords; # key words of tests to skip
260 my %enabled_keywords; # key words of tests to run
261 my %disabled; # disabled test cases
263 my $sshdid; # for socks server, ssh daemon version id
264 my $sshdvernum; # for socks server, ssh daemon version number
265 my $sshdverstr; # for socks server, ssh daemon version string
266 my $sshderror; # for socks server, ssh daemon version error
268 my $defserverlogslocktimeout = 20; # timeout to await server logs lock removal
269 my $defpostcommanddelay = 0; # delay between command and postcheck sections
271 my $timestats; # time stamping and stats generation
272 my $fullstats; # show time stats for every single test
273 my %timeprepini; # timestamp for each test preparation start
274 my %timesrvrini; # timestamp for each test required servers verification start
275 my %timesrvrend; # timestamp for each test required servers verification end
276 my %timetoolini; # timestamp for each test command run starting
277 my %timetoolend; # timestamp for each test command run stopping
278 my %timesrvrlog; # timestamp for each test server logs lock removal
279 my %timevrfyend; # timestamp for each test result verification end
281 my $testnumcheck; # test number, set in singletest sub.
284 #######################################################################
285 # variables that command line options may set
293 my $gdbthis; # run test case with gdb debugger
294 my $gdbxwin; # use windowed gdb when using gdb
295 my $keepoutfiles; # keep stdout and stderr files after tests
296 my $listonly; # only list the tests
297 my $postmortem; # display detailed info about failed tests
298 my $run_event_based; # run curl with --test-event to test the event API
300 my %run; # running server
301 my %doesntrun; # servers that don't work, identified by pidfile
302 my %serverpidfile;# all server pid file names, identified by server id
303 my %runcert; # cert file currently in use by an ssl running server
305 # torture test variables
310 #######################################################################
311 # logmsg is our general message logging subroutine.
319 # get the name of the current user
320 my $USER = $ENV{USER}; # Linux
322 $USER = $ENV{USERNAME}; # Windows
324 $USER = $ENV{LOGNAME}; # Some Unix (I think)
328 # enable memory debugging if curl is compiled with it
329 $ENV{'CURL_MEMDEBUG'} = $memdump;
330 $ENV{'CURL_ENTROPY'}="12345678";
331 $ENV{'CURL_FORCETIME'}=1; # for debug NTLM magic
336 logmsg "runtests.pl received SIG$signame, exiting\n";
337 stopservers($verbose);
338 die "Somebody sent me a SIG$signame";
340 $SIG{INT} = \&catch_zap;
341 $SIG{TERM} = \&catch_zap;
343 ##########################################################################
344 # Clear all possible '*_proxy' environment variables for various protocols
345 # to prevent them to interfere with our testing!
348 foreach $protocol (('ftp', 'http', 'ftps', 'https', 'no', 'all')) {
349 my $proxy = "${protocol}_proxy";
350 # clear lowercase version
351 delete $ENV{$proxy} if($ENV{$proxy});
352 # clear uppercase version
353 delete $ENV{uc($proxy)} if($ENV{uc($proxy)});
356 # make sure we don't get affected by other variables that control our
359 delete $ENV{'SSL_CERT_DIR'} if($ENV{'SSL_CERT_DIR'});
360 delete $ENV{'SSL_CERT_PATH'} if($ENV{'SSL_CERT_PATH'});
361 delete $ENV{'CURL_CA_BUNDLE'} if($ENV{'CURL_CA_BUNDLE'});
363 #######################################################################
364 # Load serverpidfile hash with pidfile names for all possible servers.
366 sub init_serverpidfile_hash {
367 for my $proto (('ftp', 'http', 'imap', 'pop3', 'smtp')) {
368 for my $ssl (('', 's')) {
369 for my $ipvnum ((4, 6)) {
370 for my $idnum ((1, 2, 3)) {
371 my $serv = servername_id("$proto$ssl", $ipvnum, $idnum);
372 my $pidf = server_pidfilename("$proto$ssl", $ipvnum, $idnum);
373 $serverpidfile{$serv} = $pidf;
378 for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp', 'gopher', 'httptls')) {
379 for my $ipvnum ((4, 6)) {
380 for my $idnum ((1, 2)) {
381 my $serv = servername_id($proto, $ipvnum, $idnum);
382 my $pidf = server_pidfilename($proto, $ipvnum, $idnum);
383 $serverpidfile{$serv} = $pidf;
387 for my $proto (('http', 'imap', 'pop3', 'smtp')) {
388 for my $ssl (('', 's')) {
389 my $serv = servername_id("$proto$ssl", "unix", 1);
390 my $pidf = server_pidfilename("$proto$ssl", "unix", 1);
391 $serverpidfile{$serv} = $pidf;
396 #######################################################################
397 # Check if a given child process has just died. Reaps it if so.
400 use POSIX ":sys_wait_h";
402 if((not defined $pid) || $pid <= 0) {
405 my $rc = waitpid($pid, &WNOHANG);
406 return ($rc == $pid)?1:0;
409 #######################################################################
410 # Start a new thread/process and run the given command line in there.
411 # Return the pids (yes plural) of the new child process to the parent.
414 my ($cmd, $pidfile, $timeout, $fake)=@_;
416 logmsg "startnew: $cmd\n" if ($verbose);
421 if(not defined $child) {
422 logmsg "startnew: fork() failure detected\n";
427 # Here we are the child. Run the given command.
429 # Put an "exec" in front of the command so that the child process
430 # keeps this child's process ID.
431 exec("exec $cmd") || die "Can't exec() $cmd: $!";
433 # exec() should never return back here to this process. We protect
434 # ourselves by calling die() just in case something goes really bad.
435 die "error: exec() has returned";
438 # Ugly hack but ssh client and gnutls-serv don't support pid files
440 if(open(OUT, ">$pidfile")) {
441 print OUT $child . "\n";
443 logmsg "startnew: $pidfile faked with pid=$child\n" if($verbose);
446 logmsg "startnew: failed to write fake $pidfile with pid=$child\n";
448 # could/should do a while connect fails sleep a bit and loop
450 if (checkdied($child)) {
451 logmsg "startnew: child process has failed to start\n" if($verbose);
456 my $count = $timeout;
458 if(-f $pidfile && -s $pidfile && open(PID, "<$pidfile")) {
461 if(($pid2 > 0) && pidexists($pid2)) {
462 # if $pid2 is valid, then make sure this pid is alive, as
463 # otherwise it is just likely to be the _previous_ pidfile or
467 # invalidate $pid2 if not actually alive
470 if (checkdied($child)) {
471 logmsg "startnew: child process has died, server might start up\n"
473 # We can't just abort waiting for the server with a
475 # because the server might have forked and could still start
476 # up normally. Instead, just reduce the amount of time we remain
483 # Return two PIDs, the one for the child process we spawned and the one
484 # reported by the server itself (in case it forked again on its own).
485 # Both (potentially) need to be killed at the end of the test.
486 return ($child, $pid2);
490 #######################################################################
491 # Check for a command in the PATH of the test server.
495 my @paths=(split(":", $ENV{'PATH'}), "/usr/sbin", "/usr/local/sbin",
496 "/sbin", "/usr/bin", "/usr/local/bin",
497 "./libtest/.libs", "./libtest");
499 if( -x "$_/$cmd" && ! -d "$_/$cmd") {
500 # executable bit but not a directory!
506 #######################################################################
507 # Get the list of tests that the tests/data/Makefile.am knows about!
511 my @dist = `cd data && make show`;
512 $disttests = join("", @dist);
515 #######################################################################
516 # Check for a command in the PATH of the machine running curl.
520 return checkcmd($cmd);
523 #######################################################################
524 # Run the application under test and return its return code
528 my $ret = system($cmd);
529 print "CMD ($ret): $cmd\n" if($verbose && !$torture);
532 # This is one way to test curl on a remote machine
533 # my $out = system("ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'");
534 # sleep 2; # time to allow the NFS server to be updated
538 #######################################################################
539 # Run the application under test and return its stdout
541 sub runclientoutput {
545 # This is one way to test curl on a remote machine
546 # my @out = `ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'`;
547 # sleep 2; # time to allow the NFS server to be updated
551 #######################################################################
552 # Memory allocation test and failure torture testing.
558 # remove memdump first to be sure we get a new nice and clean one
561 # First get URL from test server, ignore the output/result
564 logmsg " CMD: $testcmd\n" if($verbose);
566 # memanalyze -v is our friend, get the number of allocations made
568 my @out = `$memanalyze -v $memdump`;
570 if(/^Allocations: (\d+)/) {
576 logmsg " found no allocs to make fail\n";
580 logmsg " $count allocations to make fail\n";
582 for ( 1 .. $count ) {
587 if($tortalloc && ($tortalloc != $limit)) {
592 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
594 my $now = sprintf("%02d:%02d:%02d ", $hour, $min, $sec);
595 logmsg "Fail alloc no: $limit at $now\r";
598 # make the memory allocation function number $limit return failure
599 $ENV{'CURL_MEMLIMIT'} = $limit;
601 # remove memdump first to be sure we get a new nice and clean one
604 logmsg "*** Alloc number $limit is now set to fail ***\n" if($gdbthis);
611 $ret = runclient($testcmd);
613 #logmsg "$_ Returned " . ($ret >> 8) . "\n";
615 # Now clear the variable again
616 delete $ENV{'CURL_MEMLIMIT'} if($ENV{'CURL_MEMLIMIT'});
619 # there's core file present now!
620 logmsg " core dumped\n";
625 # verify that it returns a proper error code, doesn't leak memory
626 # and doesn't core dump
627 if(($ret & 255) || ($ret >> 8) >= 128) {
628 logmsg " system() returned $ret\n";
632 my @memdata=`$memanalyze $memdump`;
636 # well it could be other memory problems as well, but
637 # we call it leak for short here
642 logmsg "** MEMORY FAILURE\n";
644 logmsg `$memanalyze -l $memdump`;
649 logmsg " Failed on alloc number $limit in test.\n",
650 " invoke with \"-t$limit\" to repeat this single case.\n";
651 stopservers($verbose);
656 logmsg "torture OK\n";
660 #######################################################################
661 # Stop a test server along with pids which aren't in the %run hash yet.
662 # This also stops all servers which are relative to the given one.
665 my ($server, $pidlist) = @_;
667 # kill sockfilter processes for pingpong relative server
669 if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
671 my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
672 my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
673 killsockfilters($proto, $ipvnum, $idnum, $verbose);
676 # All servers relative to the given one must be stopped also
679 if($server =~ /^(ftp|http|imap|pop3|smtp|httppipe)s((\d*)(-ipv6|-unix|))$/) {
680 # given a stunnel based ssl server, also kill non-ssl underlying one
681 push @killservers, "${1}${2}";
683 elsif($server =~ /^(ftp|http|imap|pop3|smtp|httppipe)((\d*)(-ipv6|-unix|))$/) {
684 # given a non-ssl server, also kill stunnel based ssl piggybacking one
685 push @killservers, "${1}s${2}";
687 elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
688 # given a socks server, also kill ssh underlying one
689 push @killservers, "ssh${2}";
691 elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
692 # given a ssh server, also kill socks piggybacking one
693 push @killservers, "socks${2}";
695 push @killservers, $server;
697 # kill given pids and server relative ones clearing them in %run hash
699 foreach my $server (@killservers) {
701 # we must prepend a space since $pidlist may already contain a pid
702 $pidlist .= " $run{$server}";
705 $runcert{$server} = 0 if($runcert{$server});
707 killpid($verbose, $pidlist);
709 # cleanup server pid files
711 foreach my $server (@killservers) {
712 my $pidfile = $serverpidfile{$server};
713 my $pid = processexists($pidfile);
715 logmsg "Warning: $server server unexpectedly alive\n";
716 killpid($verbose, $pid);
718 unlink($pidfile) if(-f $pidfile);
722 #######################################################################
723 # Verify that the server that runs on $ip, $port is our server. This also
724 # implies that we can speak with it, as there might be occasions when the
725 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
726 # assign requested address")
729 my ($proto, $ipvnum, $idnum, $ip, $port_or_path) = @_;
730 my $server = servername_id($proto, $ipvnum, $idnum);
733 # $port_or_path contains a path for Unix sockets, sws ignores the port
734 my $port = ($ipvnum eq "unix") ? 80 : $port_or_path;
736 my $verifyout = "$LOGDIR/".
737 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
738 unlink($verifyout) if(-f $verifyout);
740 my $verifylog = "$LOGDIR/".
741 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
742 unlink($verifylog) if(-f $verifylog);
744 if($proto eq "gopher") {
749 my $flags = "--max-time $server_response_maxtime ";
750 $flags .= "--output $verifyout ";
751 $flags .= "--silent ";
752 $flags .= "--verbose ";
753 $flags .= "--globoff ";
754 $flags .= "--unix-socket '$port_or_path' " if $ipvnum eq "unix";
755 $flags .= "-1 " if($has_axtls);
756 $flags .= "--insecure " if($proto eq 'https');
757 $flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\"";
759 my $cmd = "$VCURL $flags 2>$verifylog";
761 # verify if our/any server is running on this port
762 logmsg "RUN: $cmd\n" if($verbose);
763 my $res = runclient($cmd);
765 $res >>= 8; # rotate the result
767 logmsg "RUN: curl command died with a coredump\n";
771 if($res && $verbose) {
772 logmsg "RUN: curl command returned $res\n";
773 if(open(FILE, "<$verifylog")) {
774 while(my $string = <FILE>) {
775 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
782 if(open(FILE, "<$verifyout")) {
783 while(my $string = <FILE>) {
785 last; # only want first line
790 if($data && ($data =~ /WE ROOLZ: (\d+)/)) {
794 # curl: (6) Couldn't resolve host '::1'
795 logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
798 elsif($data || ($res && ($res != 7))) {
799 logmsg "RUN: Unknown server on our $server port: $port ($res)\n";
805 #######################################################################
806 # Verify that the server that runs on $ip, $port is our server. This also
807 # implies that we can speak with it, as there might be occasions when the
808 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
809 # assign requested address")
812 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
813 my $server = servername_id($proto, $ipvnum, $idnum);
818 my $verifylog = "$LOGDIR/".
819 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
820 unlink($verifylog) if(-f $verifylog);
822 if($proto eq "ftps") {
823 $extra .= "--insecure --ftp-ssl-control ";
826 my $flags = "--max-time $server_response_maxtime ";
827 $flags .= "--silent ";
828 $flags .= "--verbose ";
829 $flags .= "--globoff ";
831 $flags .= "\"$proto://$ip:$port/verifiedserver\"";
833 my $cmd = "$VCURL $flags 2>$verifylog";
835 # check if this is our server running on this port:
836 logmsg "RUN: $cmd\n" if($verbose);
837 my @data = runclientoutput($cmd);
839 my $res = $? >> 8; # rotate the result
841 logmsg "RUN: curl command died with a coredump\n";
845 foreach my $line (@data) {
846 if($line =~ /WE ROOLZ: (\d+)/) {
847 # this is our test server with a known pid!
852 if($pid <= 0 && @data && $data[0]) {
853 # this is not a known server
854 logmsg "RUN: Unknown server on our $server port: $port\n";
857 # we can/should use the time it took to verify the FTP server as a measure
858 # on how fast/slow this host/FTP is.
859 my $took = int(0.5+time()-$time);
862 logmsg "RUN: Verifying our test $server server took $took seconds\n";
864 $ftpchecktime = $took>=1?$took:1; # make sure it never is below 1
869 #######################################################################
870 # Verify that the server that runs on $ip, $port is our server. This also
871 # implies that we can speak with it, as there might be occasions when the
872 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
873 # assign requested address")
876 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
877 my $server = servername_id($proto, $ipvnum, $idnum);
880 my $verifyout = "$LOGDIR/".
881 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
882 unlink($verifyout) if(-f $verifyout);
884 my $verifylog = "$LOGDIR/".
885 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
886 unlink($verifylog) if(-f $verifylog);
888 my $flags = "--max-time $server_response_maxtime ";
889 $flags .= "--output $verifyout ";
890 $flags .= "--silent ";
891 $flags .= "--verbose ";
892 $flags .= "--globoff ";
893 # currently verification is done using http
894 $flags .= "\"http://$ip:$port/verifiedserver\"";
896 my $cmd = "$VCURL $flags 2>$verifylog";
898 # verify if our/any server is running on this port
899 logmsg "RUN: $cmd\n" if($verbose);
900 my $res = runclient($cmd);
902 $res >>= 8; # rotate the result
904 logmsg "RUN: curl command died with a coredump\n";
908 if($res && $verbose) {
909 logmsg "RUN: curl command returned $res\n";
910 if(open(FILE, "<$verifylog")) {
911 while(my $string = <FILE>) {
912 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
919 if(open(FILE, "<$verifyout")) {
920 while(my $string = <FILE>) {
922 last; # only want first line
927 if($data && ($data =~ /RTSP_SERVER WE ROOLZ: (\d+)/)) {
931 # curl: (6) Couldn't resolve host '::1'
932 logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
935 elsif($data || ($res != 7)) {
936 logmsg "RUN: Unknown server on our $server port: $port\n";
942 #######################################################################
943 # Verify that the ssh server has written out its pidfile, recovering
944 # the pid from the file and returning it if a process with that pid is
948 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
949 my $server = servername_id($proto, $ipvnum, $idnum);
950 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
952 if(open(FILE, "<$pidfile")) {
957 # if we have a pid it is actually our ssh server,
958 # since runsshserver() unlinks previous pidfile
959 if(!pidexists($pid)) {
960 logmsg "RUN: SSH server has died after starting up\n";
969 #######################################################################
970 # Verify that we can connect to the sftp server, properly authenticate
971 # with generated config and key files and run a simple remote pwd.
974 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
975 my $server = servername_id($proto, $ipvnum, $idnum);
977 # Find out sftp client canonical file name
978 my $sftp = find_sftp();
980 logmsg "RUN: SFTP server cannot find $sftpexe\n";
983 # Find out ssh client canonical file name
984 my $ssh = find_ssh();
986 logmsg "RUN: SFTP server cannot find $sshexe\n";
989 # Connect to sftp server, authenticate and run a remote pwd
990 # command using our generated configuration and key files
991 my $cmd = "\"$sftp\" -b $sftpcmds -F $sftpconfig -S \"$ssh\" $ip > $sftplog 2>&1";
992 my $res = runclient($cmd);
993 # Search for pwd command response in log file
994 if(open(SFTPLOGFILE, "<$sftplog")) {
995 while(<SFTPLOGFILE>) {
996 if(/^Remote working directory: /) {
1006 #######################################################################
1007 # Verify that the non-stunnel HTTP TLS extensions capable server that runs
1008 # on $ip, $port is our server. This also implies that we can speak with it,
1009 # as there might be occasions when the server runs fine but we cannot talk
1010 # to it ("Failed to connect to ::1: Can't assign requested address")
1013 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1014 my $server = servername_id($proto, $ipvnum, $idnum);
1015 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
1018 my $verifyout = "$LOGDIR/".
1019 servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
1020 unlink($verifyout) if(-f $verifyout);
1022 my $verifylog = "$LOGDIR/".
1023 servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
1024 unlink($verifylog) if(-f $verifylog);
1026 my $flags = "--max-time $server_response_maxtime ";
1027 $flags .= "--output $verifyout ";
1028 $flags .= "--verbose ";
1029 $flags .= "--globoff ";
1030 $flags .= "--insecure ";
1031 $flags .= "--tlsauthtype SRP ";
1032 $flags .= "--tlsuser jsmith ";
1033 $flags .= "--tlspassword abc ";
1034 $flags .= "\"https://$ip:$port/verifiedserver\"";
1036 my $cmd = "$VCURL $flags 2>$verifylog";
1038 # verify if our/any server is running on this port
1039 logmsg "RUN: $cmd\n" if($verbose);
1040 my $res = runclient($cmd);
1042 $res >>= 8; # rotate the result
1044 logmsg "RUN: curl command died with a coredump\n";
1048 if($res && $verbose) {
1049 logmsg "RUN: curl command returned $res\n";
1050 if(open(FILE, "<$verifylog")) {
1051 while(my $string = <FILE>) {
1052 logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
1059 if(open(FILE, "<$verifyout")) {
1060 while(my $string = <FILE>) {
1066 if($data && ($data =~ /(GNUTLS|GnuTLS)/) && open(FILE, "<$pidfile")) {
1070 # if we have a pid it is actually our httptls server,
1071 # since runhttptlsserver() unlinks previous pidfile
1072 if(!pidexists($pid)) {
1073 logmsg "RUN: $server server has died after starting up\n";
1082 # curl: (6) Couldn't resolve host '::1'
1083 logmsg "RUN: failed to resolve host (https://$ip:$port/verifiedserver)\n";
1086 elsif($data || ($res && ($res != 7))) {
1087 logmsg "RUN: Unknown server on our $server port: $port ($res)\n";
1093 #######################################################################
1094 # STUB for verifying socks
1097 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1098 my $server = servername_id($proto, $ipvnum, $idnum);
1099 my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
1101 if(open(FILE, "<$pidfile")) {
1106 # if we have a pid it is actually our socks server,
1107 # since runsocksserver() unlinks previous pidfile
1108 if(!pidexists($pid)) {
1109 logmsg "RUN: SOCKS server has died after starting up\n";
1118 #######################################################################
1119 # Verify that the server that runs on $ip, $port is our server.
1120 # Retry over several seconds before giving up. The ssh server in
1121 # particular can take a long time to start if it needs to generate
1122 # keys on a slow or loaded host.
1124 # Just for convenience, test harness uses 'https' and 'httptls' literals
1125 # as values for 'proto' variable in order to differentiate different
1126 # servers. 'https' literal is used for stunnel based https test servers,
1127 # and 'httptls' is used for non-stunnel https test servers.
1130 my %protofunc = ('http' => \&verifyhttp,
1131 'https' => \&verifyhttp,
1132 'rtsp' => \&verifyrtsp,
1133 'ftp' => \&verifyftp,
1134 'pop3' => \&verifyftp,
1135 'imap' => \&verifyftp,
1136 'smtp' => \&verifyftp,
1137 'httppipe' => \&verifyhttp,
1138 'ftps' => \&verifyftp,
1139 'tftp' => \&verifyftp,
1140 'ssh' => \&verifyssh,
1141 'socks' => \&verifysocks,
1142 'gopher' => \&verifyhttp,
1143 'httptls' => \&verifyhttptls);
1146 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1148 my $count = 30; # try for this many seconds
1152 my $fun = $protofunc{$proto};
1154 $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port);
1160 # a real failure, stop trying and bail out
1168 #######################################################################
1169 # Single shot server responsiveness test. This should only be used
1170 # to verify that a server present in %run hash is still functional
1172 sub responsiveserver {
1173 my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
1174 my $prev_verbose = $verbose;
1177 my $fun = $protofunc{$proto};
1178 my $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port);
1179 $verbose = $prev_verbose;
1182 return 1; # responsive
1185 my $srvrname = servername_str($proto, $ipvnum, $idnum);
1186 logmsg " server precheck FAILED (unresponsive $srvrname server)\n";
1190 #######################################################################
1191 # start the http server
1194 my ($proto, $verbose, $alt, $port_or_path) = @_;
1203 my $exe = "$perl $srcdir/httpserver.pl";
1204 my $verbose_flag = "--verbose ";
1206 if($alt eq "ipv6") {
1207 # if IPv6, use a different setup
1211 elsif($alt eq "proxy") {
1212 # basically the same, but another ID
1215 elsif($alt eq "pipe") {
1216 # basically the same, but another ID
1218 $exe = "python $srcdir/http_pipe.py";
1219 $verbose_flag .= "1 ";
1221 elsif($alt eq "unix") {
1222 # IP (protocol) is mutually exclusive with Unix sockets
1226 $server = servername_id($proto, $ipvnum, $idnum);
1228 $pidfile = $serverpidfile{$server};
1230 # don't retry if the server doesn't work
1231 if ($doesntrun{$pidfile}) {
1235 my $pid = processexists($pidfile);
1237 stopserver($server, "$pid");
1239 unlink($pidfile) if(-f $pidfile);
1241 $srvrname = servername_str($proto, $ipvnum, $idnum);
1243 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1245 $flags .= "--gopher " if($proto eq "gopher");
1246 $flags .= "--connect $HOSTIP " if($alt eq "proxy");
1247 $flags .= $verbose_flag if($debugprotocol);
1248 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1249 $flags .= "--id $idnum " if($idnum > 1);
1250 if($ipvnum eq "unix") {
1251 $flags .= "--unix-socket '$port_or_path' ";
1253 $flags .= "--ipv$ipvnum --port $port_or_path ";
1255 $flags .= "--srcdir \"$srcdir\"";
1257 my $cmd = "$exe $flags";
1258 my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1260 if($httppid <= 0 || !pidexists($httppid)) {
1262 logmsg "RUN: failed to start the $srvrname server\n";
1263 stopserver($server, "$pid2");
1264 displaylogs($testnumcheck);
1265 $doesntrun{$pidfile} = 1;
1269 # Server is up. Verify that we can speak to it.
1270 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
1272 logmsg "RUN: $srvrname server failed verification\n";
1273 # failed to talk to it properly. Kill the server and return failure
1274 stopserver($server, "$httppid $pid2");
1275 displaylogs($testnumcheck);
1276 $doesntrun{$pidfile} = 1;
1282 logmsg "RUN: $srvrname server is now running PID $httppid\n";
1287 return ($httppid, $pid2);
1290 #######################################################################
1291 # start the http server
1293 sub runhttp_pipeserver {
1294 my ($proto, $verbose, $alt, $port) = @_;
1304 if($alt eq "ipv6") {
1308 $server = servername_id($proto, $ipvnum, $idnum);
1310 $pidfile = $serverpidfile{$server};
1312 # don't retry if the server doesn't work
1313 if ($doesntrun{$pidfile}) {
1317 my $pid = processexists($pidfile);
1319 stopserver($server, "$pid");
1321 unlink($pidfile) if(-f $pidfile);
1323 $srvrname = servername_str($proto, $ipvnum, $idnum);
1325 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1327 $flags .= "--verbose 1 " if($debugprotocol);
1328 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1329 $flags .= "--id $idnum " if($idnum > 1);
1330 $flags .= "--port $port --srcdir \"$srcdir\"";
1332 my $cmd = "$srcdir/http_pipe.py $flags";
1333 my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1335 if($httppid <= 0 || !pidexists($httppid)) {
1337 logmsg "RUN: failed to start the $srvrname server\n";
1338 stopserver($server, "$pid2");
1339 displaylogs($testnumcheck);
1340 $doesntrun{$pidfile} = 1;
1344 # Server is up. Verify that we can speak to it.
1345 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1347 logmsg "RUN: $srvrname server failed verification\n";
1348 # failed to talk to it properly. Kill the server and return failure
1349 stopserver($server, "$httppid $pid2");
1350 displaylogs($testnumcheck);
1351 $doesntrun{$pidfile} = 1;
1357 logmsg "RUN: $srvrname server is now running PID $httppid\n";
1362 return ($httppid, $pid2);
1365 #######################################################################
1366 # start the https stunnel based server
1368 sub runhttpsserver {
1369 my ($verbose, $ipv6, $certfile) = @_;
1370 my $proto = 'https';
1371 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1372 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1384 $server = servername_id($proto, $ipvnum, $idnum);
1386 $pidfile = $serverpidfile{$server};
1388 # don't retry if the server doesn't work
1389 if ($doesntrun{$pidfile}) {
1393 my $pid = processexists($pidfile);
1395 stopserver($server, "$pid");
1397 unlink($pidfile) if(-f $pidfile);
1399 $srvrname = servername_str($proto, $ipvnum, $idnum);
1401 $certfile = 'stunnel.pem' unless($certfile);
1403 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1405 $flags .= "--verbose " if($debugprotocol);
1406 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1407 $flags .= "--id $idnum " if($idnum > 1);
1408 $flags .= "--ipv$ipvnum --proto $proto ";
1409 $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
1410 $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
1411 $flags .= "--connect $HTTPPORT --accept $HTTPSPORT";
1413 my $cmd = "$perl $srcdir/secureserver.pl $flags";
1414 my ($httpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1416 if($httpspid <= 0 || !pidexists($httpspid)) {
1418 logmsg "RUN: failed to start the $srvrname server\n";
1419 stopserver($server, "$pid2");
1420 displaylogs($testnumcheck);
1421 $doesntrun{$pidfile} = 1;
1425 # Server is up. Verify that we can speak to it.
1426 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $HTTPSPORT);
1428 logmsg "RUN: $srvrname server failed verification\n";
1429 # failed to talk to it properly. Kill the server and return failure
1430 stopserver($server, "$httpspid $pid2");
1431 displaylogs($testnumcheck);
1432 $doesntrun{$pidfile} = 1;
1435 # Here pid3 is actually the pid returned by the unsecure-http server.
1437 $runcert{$server} = $certfile;
1440 logmsg "RUN: $srvrname server is now running PID $httpspid\n";
1445 return ($httpspid, $pid2);
1448 #######################################################################
1449 # start the non-stunnel HTTP TLS extensions capable server
1451 sub runhttptlsserver {
1452 my ($verbose, $ipv6) = @_;
1453 my $proto = "httptls";
1454 my $port = ($ipv6 && ($ipv6 =~ /6$/)) ? $HTTPTLS6PORT : $HTTPTLSPORT;
1455 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1456 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1468 $server = servername_id($proto, $ipvnum, $idnum);
1470 $pidfile = $serverpidfile{$server};
1472 # don't retry if the server doesn't work
1473 if ($doesntrun{$pidfile}) {
1477 my $pid = processexists($pidfile);
1479 stopserver($server, "$pid");
1481 unlink($pidfile) if(-f $pidfile);
1483 $srvrname = servername_str($proto, $ipvnum, $idnum);
1485 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1487 $flags .= "--http ";
1488 $flags .= "--debug 1 " if($debugprotocol);
1489 $flags .= "--port $port ";
1490 $flags .= "--priority NORMAL:+SRP ";
1491 $flags .= "--srppasswd $srcdir/certs/srp-verifier-db ";
1492 $flags .= "--srppasswdconf $srcdir/certs/srp-verifier-conf";
1494 my $cmd = "$httptlssrv $flags > $logfile 2>&1";
1495 my ($httptlspid, $pid2) = startnew($cmd, $pidfile, 10, 1); # fake pidfile
1497 if($httptlspid <= 0 || !pidexists($httptlspid)) {
1499 logmsg "RUN: failed to start the $srvrname server\n";
1500 stopserver($server, "$pid2");
1501 displaylogs($testnumcheck);
1502 $doesntrun{$pidfile} = 1;
1506 # Server is up. Verify that we can speak to it. PID is from fake pidfile
1507 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1509 logmsg "RUN: $srvrname server failed verification\n";
1510 # failed to talk to it properly. Kill the server and return failure
1511 stopserver($server, "$httptlspid $pid2");
1512 displaylogs($testnumcheck);
1513 $doesntrun{$pidfile} = 1;
1519 logmsg "RUN: $srvrname server is now running PID $httptlspid\n";
1524 return ($httptlspid, $pid2);
1527 #######################################################################
1528 # start the pingpong server (FTP, POP3, IMAP, SMTP)
1530 sub runpingpongserver {
1531 my ($proto, $id, $verbose, $ipv6) = @_;
1533 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1534 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1535 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1542 if($proto eq "ftp") {
1543 $port = ($idnum>1)?$FTP2PORT:$FTPPORT;
1546 # if IPv6, use a different setup
1550 elsif($proto eq "pop3") {
1551 $port = ($ipvnum==6) ? $POP36PORT : $POP3PORT;
1553 elsif($proto eq "imap") {
1554 $port = ($ipvnum==6) ? $IMAP6PORT : $IMAPPORT;
1556 elsif($proto eq "smtp") {
1557 $port = ($ipvnum==6) ? $SMTP6PORT : $SMTPPORT;
1560 print STDERR "Unsupported protocol $proto!!\n";
1564 $server = servername_id($proto, $ipvnum, $idnum);
1566 $pidfile = $serverpidfile{$server};
1568 # don't retry if the server doesn't work
1569 if ($doesntrun{$pidfile}) {
1573 my $pid = processexists($pidfile);
1575 stopserver($server, "$pid");
1577 unlink($pidfile) if(-f $pidfile);
1579 $srvrname = servername_str($proto, $ipvnum, $idnum);
1581 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1583 $flags .= "--verbose " if($debugprotocol);
1584 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1585 $flags .= "--srcdir \"$srcdir\" --proto $proto ";
1586 $flags .= "--id $idnum " if($idnum > 1);
1587 $flags .= "--ipv$ipvnum --port $port --addr \"$ip\"";
1589 my $cmd = "$perl $srcdir/ftpserver.pl $flags";
1590 my ($ftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1592 if($ftppid <= 0 || !pidexists($ftppid)) {
1594 logmsg "RUN: failed to start the $srvrname server\n";
1595 stopserver($server, "$pid2");
1596 displaylogs($testnumcheck);
1597 $doesntrun{$pidfile} = 1;
1601 # Server is up. Verify that we can speak to it.
1602 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1604 logmsg "RUN: $srvrname server failed verification\n";
1605 # failed to talk to it properly. Kill the server and return failure
1606 stopserver($server, "$ftppid $pid2");
1607 displaylogs($testnumcheck);
1608 $doesntrun{$pidfile} = 1;
1615 logmsg "RUN: $srvrname server is now running PID $ftppid\n";
1620 return ($pid2, $ftppid);
1623 #######################################################################
1624 # start the ftps server (or rather, tunnel)
1627 my ($verbose, $ipv6, $certfile) = @_;
1629 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
1630 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
1642 $server = servername_id($proto, $ipvnum, $idnum);
1644 $pidfile = $serverpidfile{$server};
1646 # don't retry if the server doesn't work
1647 if ($doesntrun{$pidfile}) {
1651 my $pid = processexists($pidfile);
1653 stopserver($server, "$pid");
1655 unlink($pidfile) if(-f $pidfile);
1657 $srvrname = servername_str($proto, $ipvnum, $idnum);
1659 $certfile = 'stunnel.pem' unless($certfile);
1661 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1663 $flags .= "--verbose " if($debugprotocol);
1664 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1665 $flags .= "--id $idnum " if($idnum > 1);
1666 $flags .= "--ipv$ipvnum --proto $proto ";
1667 $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
1668 $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
1669 $flags .= "--connect $FTPPORT --accept $FTPSPORT";
1671 my $cmd = "$perl $srcdir/secureserver.pl $flags";
1672 my ($ftpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1674 if($ftpspid <= 0 || !pidexists($ftpspid)) {
1676 logmsg "RUN: failed to start the $srvrname server\n";
1677 stopserver($server, "$pid2");
1678 displaylogs($testnumcheck);
1679 $doesntrun{$pidfile} = 1;
1683 # Server is up. Verify that we can speak to it.
1684 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $FTPSPORT);
1686 logmsg "RUN: $srvrname server failed verification\n";
1687 # failed to talk to it properly. Kill the server and return failure
1688 stopserver($server, "$ftpspid $pid2");
1689 displaylogs($testnumcheck);
1690 $doesntrun{$pidfile} = 1;
1693 # Here pid3 is actually the pid returned by the unsecure-ftp server.
1695 $runcert{$server} = $certfile;
1698 logmsg "RUN: $srvrname server is now running PID $ftpspid\n";
1703 return ($ftpspid, $pid2);
1706 #######################################################################
1707 # start the tftp server
1710 my ($id, $verbose, $ipv6) = @_;
1711 my $port = $TFTPPORT;
1715 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1723 # if IPv6, use a different setup
1729 $server = servername_id($proto, $ipvnum, $idnum);
1731 $pidfile = $serverpidfile{$server};
1733 # don't retry if the server doesn't work
1734 if ($doesntrun{$pidfile}) {
1738 my $pid = processexists($pidfile);
1740 stopserver($server, "$pid");
1742 unlink($pidfile) if(-f $pidfile);
1744 $srvrname = servername_str($proto, $ipvnum, $idnum);
1746 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1748 $flags .= "--verbose " if($debugprotocol);
1749 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1750 $flags .= "--id $idnum " if($idnum > 1);
1751 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1753 my $cmd = "$perl $srcdir/tftpserver.pl $flags";
1754 my ($tftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1756 if($tftppid <= 0 || !pidexists($tftppid)) {
1758 logmsg "RUN: failed to start the $srvrname server\n";
1759 stopserver($server, "$pid2");
1760 displaylogs($testnumcheck);
1761 $doesntrun{$pidfile} = 1;
1765 # Server is up. Verify that we can speak to it.
1766 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1768 logmsg "RUN: $srvrname server failed verification\n";
1769 # failed to talk to it properly. Kill the server and return failure
1770 stopserver($server, "$tftppid $pid2");
1771 displaylogs($testnumcheck);
1772 $doesntrun{$pidfile} = 1;
1778 logmsg "RUN: $srvrname server is now running PID $tftppid\n";
1783 return ($pid2, $tftppid);
1787 #######################################################################
1788 # start the rtsp server
1791 my ($verbose, $ipv6) = @_;
1792 my $port = $RTSPPORT;
1804 # if IPv6, use a different setup
1810 $server = servername_id($proto, $ipvnum, $idnum);
1812 $pidfile = $serverpidfile{$server};
1814 # don't retry if the server doesn't work
1815 if ($doesntrun{$pidfile}) {
1819 my $pid = processexists($pidfile);
1821 stopserver($server, "$pid");
1823 unlink($pidfile) if(-f $pidfile);
1825 $srvrname = servername_str($proto, $ipvnum, $idnum);
1827 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1829 $flags .= "--verbose " if($debugprotocol);
1830 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
1831 $flags .= "--id $idnum " if($idnum > 1);
1832 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
1834 my $cmd = "$perl $srcdir/rtspserver.pl $flags";
1835 my ($rtsppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
1837 if($rtsppid <= 0 || !pidexists($rtsppid)) {
1839 logmsg "RUN: failed to start the $srvrname server\n";
1840 stopserver($server, "$pid2");
1841 displaylogs($testnumcheck);
1842 $doesntrun{$pidfile} = 1;
1846 # Server is up. Verify that we can speak to it.
1847 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1849 logmsg "RUN: $srvrname server failed verification\n";
1850 # failed to talk to it properly. Kill the server and return failure
1851 stopserver($server, "$rtsppid $pid2");
1852 displaylogs($testnumcheck);
1853 $doesntrun{$pidfile} = 1;
1859 logmsg "RUN: $srvrname server is now running PID $rtsppid\n";
1864 return ($rtsppid, $pid2);
1868 #######################################################################
1869 # Start the ssh (scp/sftp) server
1872 my ($id, $verbose, $ipv6) = @_;
1874 my $port = $SSHPORT;
1875 my $socksport = $SOCKSPORT;
1878 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1885 $server = servername_id($proto, $ipvnum, $idnum);
1887 $pidfile = $serverpidfile{$server};
1889 # don't retry if the server doesn't work
1890 if ($doesntrun{$pidfile}) {
1894 my $pid = processexists($pidfile);
1896 stopserver($server, "$pid");
1898 unlink($pidfile) if(-f $pidfile);
1900 $srvrname = servername_str($proto, $ipvnum, $idnum);
1902 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
1904 $flags .= "--verbose " if($verbose);
1905 $flags .= "--debugprotocol " if($debugprotocol);
1906 $flags .= "--pidfile \"$pidfile\" ";
1907 $flags .= "--id $idnum " if($idnum > 1);
1908 $flags .= "--ipv$ipvnum --addr \"$ip\" ";
1909 $flags .= "--sshport $port --socksport $socksport ";
1910 $flags .= "--user \"$USER\"";
1912 my $cmd = "$perl $srcdir/sshserver.pl $flags";
1913 my ($sshpid, $pid2) = startnew($cmd, $pidfile, 60, 0);
1915 # on loaded systems sshserver start up can take longer than the timeout
1916 # passed to startnew, when this happens startnew completes without being
1917 # able to read the pidfile and consequently returns a zero pid2 above.
1919 if($sshpid <= 0 || !pidexists($sshpid)) {
1921 logmsg "RUN: failed to start the $srvrname server\n";
1922 stopserver($server, "$pid2");
1923 $doesntrun{$pidfile} = 1;
1927 # ssh server verification allows some extra time for the server to start up
1928 # and gives us the opportunity of recovering the pid from the pidfile, when
1929 # this verification succeeds the recovered pid is assigned to pid2.
1931 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
1933 logmsg "RUN: $srvrname server failed verification\n";
1934 # failed to fetch server pid. Kill the server and return failure
1935 stopserver($server, "$sshpid $pid2");
1936 $doesntrun{$pidfile} = 1;
1941 # once it is known that the ssh server is alive, sftp server verification
1942 # is performed actually connecting to it, authenticating and performing a
1943 # very simple remote command. This verification is tried only one time.
1945 $sshdlog = server_logfilename($LOGDIR, 'ssh', $ipvnum, $idnum);
1946 $sftplog = server_logfilename($LOGDIR, 'sftp', $ipvnum, $idnum);
1948 if(verifysftp('sftp', $ipvnum, $idnum, $ip, $port) < 1) {
1949 logmsg "RUN: SFTP server failed verification\n";
1950 # failed to talk to it properly. Kill the server and return failure
1952 display_sftpconfig();
1954 display_sshdconfig();
1955 stopserver($server, "$sshpid $pid2");
1956 $doesntrun{$pidfile} = 1;
1961 logmsg "RUN: $srvrname server is now running PID $pid2\n";
1964 return ($pid2, $sshpid);
1967 #######################################################################
1968 # Start the socks server
1970 sub runsocksserver {
1971 my ($id, $verbose, $ipv6) = @_;
1973 my $port = $SOCKSPORT;
1974 my $proto = 'socks';
1976 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
1983 $server = servername_id($proto, $ipvnum, $idnum);
1985 $pidfile = $serverpidfile{$server};
1987 # don't retry if the server doesn't work
1988 if ($doesntrun{$pidfile}) {
1992 my $pid = processexists($pidfile);
1994 stopserver($server, "$pid");
1996 unlink($pidfile) if(-f $pidfile);
1998 $srvrname = servername_str($proto, $ipvnum, $idnum);
2000 $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
2002 # The ssh server must be already running
2004 logmsg "RUN: SOCKS server cannot find running SSH server\n";
2005 $doesntrun{$pidfile} = 1;
2009 # Find out ssh daemon canonical file name
2010 my $sshd = find_sshd();
2012 logmsg "RUN: SOCKS server cannot find $sshdexe\n";
2013 $doesntrun{$pidfile} = 1;
2017 # Find out ssh daemon version info
2018 ($sshdid, $sshdvernum, $sshdverstr, $sshderror) = sshversioninfo($sshd);
2020 # Not an OpenSSH or SunSSH ssh daemon
2021 logmsg "$sshderror\n" if($verbose);
2022 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
2023 $doesntrun{$pidfile} = 1;
2026 logmsg "ssh server found $sshd is $sshdverstr\n" if($verbose);
2028 # Find out ssh client canonical file name
2029 my $ssh = find_ssh();
2031 logmsg "RUN: SOCKS server cannot find $sshexe\n";
2032 $doesntrun{$pidfile} = 1;
2036 # Find out ssh client version info
2037 my ($sshid, $sshvernum, $sshverstr, $ssherror) = sshversioninfo($ssh);
2039 # Not an OpenSSH or SunSSH ssh client
2040 logmsg "$ssherror\n" if($verbose);
2041 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
2042 $doesntrun{$pidfile} = 1;
2046 # Verify minimum ssh client version
2047 if((($sshid =~ /OpenSSH/) && ($sshvernum < 299)) ||
2048 (($sshid =~ /SunSSH/) && ($sshvernum < 100))) {
2049 logmsg "ssh client found $ssh is $sshverstr\n";
2050 logmsg "SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later\n";
2051 $doesntrun{$pidfile} = 1;
2054 logmsg "ssh client found $ssh is $sshverstr\n" if($verbose);
2056 # Verify if ssh client and ssh daemon versions match
2057 if(($sshdid ne $sshid) || ($sshdvernum != $sshvernum)) {
2058 # Our test harness might work with slightly mismatched versions
2059 logmsg "Warning: version mismatch: sshd $sshdverstr - ssh $sshverstr\n"
2063 # Config file options for ssh client are previously set from sshserver.pl
2064 if(! -e $sshconfig) {
2065 logmsg "RUN: SOCKS server cannot find $sshconfig\n";
2066 $doesntrun{$pidfile} = 1;
2070 $sshlog = server_logfilename($LOGDIR, 'socks', $ipvnum, $idnum);
2072 # start our socks server
2073 my $cmd="\"$ssh\" -N -F $sshconfig $ip > $sshlog 2>&1";
2074 my ($sshpid, $pid2) = startnew($cmd, $pidfile, 30, 1); # fake pidfile
2076 if($sshpid <= 0 || !pidexists($sshpid)) {
2078 logmsg "RUN: failed to start the $srvrname server\n";
2080 display_sshconfig();
2082 display_sshdconfig();
2083 stopserver($server, "$pid2");
2084 $doesntrun{$pidfile} = 1;
2088 # Ugly hack but ssh doesn't support pid files. PID is from fake pidfile.
2089 my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
2091 logmsg "RUN: $srvrname server failed verification\n";
2092 # failed to talk to it properly. Kill the server and return failure
2093 stopserver($server, "$sshpid $pid2");
2094 $doesntrun{$pidfile} = 1;
2100 logmsg "RUN: $srvrname server is now running PID $pid2\n";
2103 return ($pid2, $sshpid);
2106 #######################################################################
2107 # Single shot http and gopher server responsiveness test. This should only
2108 # be used to verify that a server present in %run hash is still functional
2110 sub responsive_http_server {
2111 my ($proto, $verbose, $alt, $port_or_path) = @_;
2116 if($alt eq "ipv6") {
2117 # if IPv6, use a different setup
2121 elsif($alt eq "proxy") {
2124 elsif($alt eq "unix") {
2125 # IP (protocol) is mutually exclusive with Unix sockets
2129 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
2132 #######################################################################
2133 # Single shot pingpong server responsiveness test. This should only be
2134 # used to verify that a server present in %run hash is still functional
2136 sub responsive_pingpong_server {
2137 my ($proto, $id, $verbose, $ipv6) = @_;
2139 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
2140 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
2141 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
2143 if($proto eq "ftp") {
2144 $port = ($idnum>1)?$FTP2PORT:$FTPPORT;
2147 # if IPv6, use a different setup
2151 elsif($proto eq "pop3") {
2152 $port = ($ipvnum==6) ? $POP36PORT : $POP3PORT;
2154 elsif($proto eq "imap") {
2155 $port = ($ipvnum==6) ? $IMAP6PORT : $IMAPPORT;
2157 elsif($proto eq "smtp") {
2158 $port = ($ipvnum==6) ? $SMTP6PORT : $SMTPPORT;
2161 print STDERR "Unsupported protocol $proto!!\n";
2165 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2168 #######################################################################
2169 # Single shot rtsp server responsiveness test. This should only be
2170 # used to verify that a server present in %run hash is still functional
2172 sub responsive_rtsp_server {
2173 my ($verbose, $ipv6) = @_;
2174 my $port = $RTSPPORT;
2181 # if IPv6, use a different setup
2187 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2190 #######################################################################
2191 # Single shot tftp server responsiveness test. This should only be
2192 # used to verify that a server present in %run hash is still functional
2194 sub responsive_tftp_server {
2195 my ($id, $verbose, $ipv6) = @_;
2196 my $port = $TFTPPORT;
2200 my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
2203 # if IPv6, use a different setup
2209 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2212 #######################################################################
2213 # Single shot non-stunnel HTTP TLS extensions capable server
2214 # responsiveness test. This should only be used to verify that a
2215 # server present in %run hash is still functional
2217 sub responsive_httptls_server {
2218 my ($verbose, $ipv6) = @_;
2219 my $proto = "httptls";
2220 my $port = ($ipv6 && ($ipv6 =~ /6$/)) ? $HTTPTLS6PORT : $HTTPTLSPORT;
2221 my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
2222 my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
2225 return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
2228 #######################################################################
2229 # Remove all files in the specified directory
2237 opendir(DIR, $dir) ||
2238 return 0; # can't open dir
2239 while($file = readdir(DIR)) {
2240 if($file !~ /^\./) {
2241 unlink("$dir/$file");
2249 #######################################################################
2250 # compare test results with the expected output, we might filter off
2251 # some pattern that is allowed to differ, output test results
2254 my ($testnum, $testname, $subject, $firstref, $secondref)=@_;
2256 my $result = compareparts($firstref, $secondref);
2259 # timestamp test result verification end
2260 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
2263 logmsg "\n $testnum: $subject FAILED:\n";
2264 logmsg showdiff($LOGDIR, $firstref, $secondref);
2266 elsif(!$automakestyle) {
2271 logmsg "FAIL: $testnum - $testname - $subject\n";
2277 #######################################################################
2278 # display information about curl and the host the test suite runs on
2282 unlink($memdump); # remove this if there was one left
2291 my $curlverout="$LOGDIR/curlverout.log";
2292 my $curlvererr="$LOGDIR/curlvererr.log";
2293 my $versioncmd="$CURL --version 1>$curlverout 2>$curlvererr";
2295 unlink($curlverout);
2296 unlink($curlvererr);
2298 $versretval = runclient($versioncmd);
2301 open(VERSOUT, "<$curlverout");
2302 @version = <VERSOUT>;
2311 $curl =~ s/^(.*)(libcurl.*)/$1/g;
2314 if($curl =~ /mingw(32|64)/) {
2315 # This is a windows minw32 build, we need to translate the
2316 # given path to the "actual" windows path. The MSYS shell
2317 # has a builtin 'pwd -W' command which converts the path.
2318 $pwd = `sh -c "echo \$(pwd -W)"`;
2321 elsif ($curl =~ /win32/) {
2322 # Native Windows builds don't understand the
2323 # output of cygwin's pwd. It will be
2324 # something like /cygdrive/c/<some path>.
2326 # Use the cygpath utility to convert the
2327 # working directory to a Windows friendly
2328 # path. The -m option converts to use drive
2329 # letter:, but it uses / instead \. Forward
2330 # slashes (/) are easier for us. We don't
2331 # have to escape them to get them to curl
2333 chomp($pwd = `cygpath -m $pwd`);
2335 if ($libcurl =~ /winssl/i) {
2339 elsif ($libcurl =~ /openssl/i) {
2344 elsif ($libcurl =~ /gnutls/i) {
2349 elsif ($libcurl =~ /nss/i) {
2354 elsif ($libcurl =~ /(yassl|wolfssl)/i) {
2359 elsif ($libcurl =~ /polarssl/i) {
2363 elsif ($libcurl =~ /axtls/i) {
2367 elsif ($libcurl =~ /securetransport/i) {
2369 $ssllib="DarwinSSL";
2371 elsif ($libcurl =~ /BoringSSL/i) {
2374 $ssllib="BoringSSL";
2376 elsif ($libcurl =~ /libressl/i) {
2381 elsif ($libcurl =~ /mbedTLS/i) {
2386 if ($libcurl =~ /ares/i) {
2391 elsif($_ =~ /^Protocols: (.*)/i) {
2392 # these are the protocols compiled in to this libcurl
2393 @protocols = split(' ', lc($1));
2395 # Generate a "proto-ipv6" version of each protocol to match the
2396 # IPv6 <server> name and a "proto-unix" to match the variant which
2397 # uses Unix domain sockets. This works even if support isn't
2398 # compiled in because the <features> test will fail.
2399 push @protocols, map(("$_-ipv6", "$_-unix"), @protocols);
2401 # 'http-proxy' is used in test cases to do CONNECT through
2402 push @protocols, 'http-proxy';
2404 # 'http-pipe' is the special server for testing pipelining
2405 push @protocols, 'http-pipe';
2407 # 'none' is used in test cases to mean no server
2408 push @protocols, 'none';
2410 elsif($_ =~ /^Features: (.*)/i) {
2412 if($feat =~ /TrackMemory/i) {
2413 # built with memory tracking support (--enable-curldebug)
2414 $has_memory_tracking = 1;
2416 if($feat =~ /debug/i) {
2417 # curl was built with --enable-debug
2420 if($feat =~ /SSL/i) {
2424 if($feat =~ /Largefile/i) {
2425 # large file support
2428 if($feat =~ /IDN/i) {
2432 if($feat =~ /IPv6/i) {
2435 if($feat =~ /UnixSockets/i) {
2438 if($feat =~ /libz/i) {
2441 if($feat =~ /NTLM/i) {
2445 # Use this as a proxy for any cryptographic authentication
2448 if($feat =~ /NTLM_WB/i) {
2449 # NTLM delegation to winbind daemon ntlm_auth helper enabled
2452 if($feat =~ /SSPI/i) {
2456 if($feat =~ /GSS-API/i) {
2460 if($feat =~ /Kerberos/i) {
2464 # Use this as a proxy for any cryptographic authentication
2467 if($feat =~ /SPNEGO/i) {
2471 # Use this as a proxy for any cryptographic authentication
2474 if($feat =~ /CharConv/i) {
2478 if($feat =~ /TLS-SRP/i) {
2482 if($feat =~ /Metalink/i) {
2486 if($feat =~ /PSL/i) {
2490 if($feat =~ /AsynchDNS/i) {
2492 # this means threaded resolver
2494 $resolver="threaded";
2497 if($feat =~ /HTTP2/) {
2503 # Test harness currently uses a non-stunnel server in order to
2504 # run HTTP TLS-SRP tests required when curl is built with https
2505 # protocol support and TLS-SRP feature enabled. For convenience
2506 # 'httptls' may be included in the test harness protocols array
2507 # to differentiate this from classic stunnel based 'https' test
2513 if($_ =~ /^https(-ipv6|)$/) {
2518 if($add_httptls && (! grep /^httptls$/, @protocols)) {
2519 push @protocols, 'httptls';
2520 push @protocols, 'httptls-ipv6';
2525 logmsg "unable to get curl's version, further details are:\n";
2526 logmsg "issued command: \n";
2527 logmsg "$versioncmd \n";
2528 if ($versretval == -1) {
2529 logmsg "command failed with: \n";
2530 logmsg "$versnoexec \n";
2532 elsif ($versretval & 127) {
2533 logmsg sprintf("command died with signal %d, and %s coredump.\n",
2534 ($versretval & 127), ($versretval & 128)?"a":"no");
2537 logmsg sprintf("command exited with value %d \n", $versretval >> 8);
2539 logmsg "contents of $curlverout: \n";
2540 displaylogcontent("$curlverout");
2541 logmsg "contents of $curlvererr: \n";
2542 displaylogcontent("$curlvererr");
2543 die "couldn't get curl's version";
2546 if(-r "../lib/curl_config.h") {
2547 open(CONF, "<../lib/curl_config.h");
2549 if($_ =~ /^\#define HAVE_GETRLIMIT/) {
2557 # client has IPv6 support
2559 # check if the HTTP server has it!
2560 my @sws = `server/sws --version`;
2561 if($sws[0] =~ /IPv6/) {
2562 # HTTP server has IPv6 support!
2567 # check if the FTP server has it!
2568 @sws = `server/sockfilt --version`;
2569 if($sws[0] =~ /IPv6/) {
2570 # FTP server has IPv6 support!
2576 # client has Unix sockets support, check whether the HTTP server has it
2577 my @sws = `server/sws --version`;
2578 $http_unix = 1 if($sws[0] =~ /unix/);
2581 if(!$has_memory_tracking && $torture) {
2582 die "can't run torture tests since curl was built without ".
2583 "TrackMemory feature (--enable-curldebug)";
2586 $has_shared = `sh $CURLCONFIG --built-shared`;
2589 my $hostname=join(' ', runclientoutput("hostname"));
2590 my $hosttype=join(' ', runclientoutput("uname -a"));
2592 logmsg ("********* System characteristics ******** \n",
2595 "* Features: $feat\n",
2596 "* Host: $hostname",
2597 "* System: $hosttype");
2599 if($has_memory_tracking && $has_threadedres) {
2600 $has_memory_tracking = 0;
2602 "*** DISABLES memory tracking when using threaded resolver\n",
2606 logmsg sprintf("* Servers: %s", $stunnel?"SSL ":"");
2607 logmsg sprintf("%s", $http_ipv6?"HTTP-IPv6 ":"");
2608 logmsg sprintf("%s", $http_unix?"HTTP-unix ":"");
2609 logmsg sprintf("%s\n", $ftp_ipv6?"FTP-IPv6 ":"OFF");
2611 logmsg sprintf("* Env: %s%s", $valgrind?"Valgrind ":"",
2612 $run_event_based?"event-based ":"");
2613 logmsg sprintf("%s\n", $libtool?"Libtool ":"");
2616 logmsg "* Ports:\n";
2618 logmsg sprintf("* HTTP/%d ", $HTTPPORT);
2619 logmsg sprintf("FTP/%d ", $FTPPORT);
2620 logmsg sprintf("FTP2/%d ", $FTP2PORT);
2621 logmsg sprintf("RTSP/%d ", $RTSPPORT);
2623 logmsg sprintf("FTPS/%d ", $FTPSPORT);
2624 logmsg sprintf("HTTPS/%d ", $HTTPSPORT);
2626 logmsg sprintf("\n* TFTP/%d ", $TFTPPORT);
2628 logmsg sprintf("HTTP-IPv6/%d ", $HTTP6PORT);
2629 logmsg sprintf("RTSP-IPv6/%d ", $RTSP6PORT);
2632 logmsg sprintf("FTP-IPv6/%d ", $FTP6PORT);
2635 logmsg sprintf("TFTP-IPv6/%d ", $TFTP6PORT);
2637 logmsg sprintf("\n* GOPHER/%d ", $GOPHERPORT);
2639 logmsg sprintf("GOPHER-IPv6/%d", $GOPHERPORT);
2641 logmsg sprintf("\n* SSH/%d ", $SSHPORT);
2642 logmsg sprintf("SOCKS/%d ", $SOCKSPORT);
2643 logmsg sprintf("POP3/%d ", $POP3PORT);
2644 logmsg sprintf("IMAP/%d ", $IMAPPORT);
2645 logmsg sprintf("SMTP/%d\n", $SMTPPORT);
2647 logmsg sprintf("* POP3-IPv6/%d ", $POP36PORT);
2648 logmsg sprintf("IMAP-IPv6/%d ", $IMAP6PORT);
2649 logmsg sprintf("SMTP-IPv6/%d\n", $SMTP6PORT);
2652 logmsg sprintf("* HTTPTLS/%d ", $HTTPTLSPORT);
2654 logmsg sprintf("HTTPTLS-IPv6/%d ", $HTTPTLS6PORT);
2658 logmsg sprintf("* HTTP-PIPE/%d \n", $HTTPPIPEPORT);
2661 logmsg "* Unix socket paths:\n";
2663 logmsg sprintf("* HTTP-Unix:%s\n", $HTTPUNIXPATH);
2667 $has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys');
2669 logmsg "***************************************** \n";
2672 #######################################################################
2673 # substitute the variable stuff into either a joined up file or
2674 # a command, in either case passed by reference
2681 $$thing =~ s/%FTP6PORT/$FTP6PORT/g;
2682 $$thing =~ s/%FTP2PORT/$FTP2PORT/g;
2683 $$thing =~ s/%FTPSPORT/$FTPSPORT/g;
2684 $$thing =~ s/%FTPPORT/$FTPPORT/g;
2686 $$thing =~ s/%GOPHER6PORT/$GOPHER6PORT/g;
2687 $$thing =~ s/%GOPHERPORT/$GOPHERPORT/g;
2689 $$thing =~ s/%HTTPTLS6PORT/$HTTPTLS6PORT/g;
2690 $$thing =~ s/%HTTPTLSPORT/$HTTPTLSPORT/g;
2691 $$thing =~ s/%HTTP6PORT/$HTTP6PORT/g;
2692 $$thing =~ s/%HTTPSPORT/$HTTPSPORT/g;
2693 $$thing =~ s/%HTTPPORT/$HTTPPORT/g;
2694 $$thing =~ s/%HTTPPIPEPORT/$HTTPPIPEPORT/g;
2695 $$thing =~ s/%PROXYPORT/$HTTPPROXYPORT/g;
2697 $$thing =~ s/%IMAP6PORT/$IMAP6PORT/g;
2698 $$thing =~ s/%IMAPPORT/$IMAPPORT/g;
2700 $$thing =~ s/%POP36PORT/$POP36PORT/g;
2701 $$thing =~ s/%POP3PORT/$POP3PORT/g;
2703 $$thing =~ s/%RTSP6PORT/$RTSP6PORT/g;
2704 $$thing =~ s/%RTSPPORT/$RTSPPORT/g;
2706 $$thing =~ s/%SMTP6PORT/$SMTP6PORT/g;
2707 $$thing =~ s/%SMTPPORT/$SMTPPORT/g;
2709 $$thing =~ s/%SOCKSPORT/$SOCKSPORT/g;
2710 $$thing =~ s/%SSHPORT/$SSHPORT/g;
2712 $$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
2713 $$thing =~ s/%TFTPPORT/$TFTPPORT/g;
2715 # server Unix domain socket paths
2717 $$thing =~ s/%HTTPUNIXPATH/$HTTPUNIXPATH/g;
2719 # client IP addresses
2721 $$thing =~ s/%CLIENT6IP/$CLIENT6IP/g;
2722 $$thing =~ s/%CLIENTIP/$CLIENTIP/g;
2724 # server IP addresses
2726 $$thing =~ s/%HOST6IP/$HOST6IP/g;
2727 $$thing =~ s/%HOSTIP/$HOSTIP/g;
2731 $$thing =~ s/%CURL/$CURL/g;
2732 $$thing =~ s/%PWD/$pwd/g;
2733 $$thing =~ s/%SRCDIR/$srcdir/g;
2734 $$thing =~ s/%USER/$USER/g;
2736 # The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be
2737 # used for time-out tests and that whould work on most hosts as these
2738 # adjust for the startup/check time for this particular host. We needed
2739 # to do this to make the test suite run better on very slow hosts.
2741 my $ftp2 = $ftpchecktime * 2;
2742 my $ftp3 = $ftpchecktime * 3;
2744 $$thing =~ s/%FTPTIME2/$ftp2/g;
2745 $$thing =~ s/%FTPTIME3/$ftp3/g;
2749 $$thing =~ s/%H2CVER/$h2cver/g;
2761 #######################################################################
2762 # Provide time stamps for single test skipped events
2764 sub timestampskippedevents {
2765 my $testnum = $_[0];
2767 return if((not defined($testnum)) || ($testnum < 1));
2771 if($timevrfyend{$testnum}) {
2774 elsif($timesrvrlog{$testnum}) {
2775 $timevrfyend{$testnum} = $timesrvrlog{$testnum};
2778 elsif($timetoolend{$testnum}) {
2779 $timevrfyend{$testnum} = $timetoolend{$testnum};
2780 $timesrvrlog{$testnum} = $timetoolend{$testnum};
2782 elsif($timetoolini{$testnum}) {
2783 $timevrfyend{$testnum} = $timetoolini{$testnum};
2784 $timesrvrlog{$testnum} = $timetoolini{$testnum};
2785 $timetoolend{$testnum} = $timetoolini{$testnum};
2787 elsif($timesrvrend{$testnum}) {
2788 $timevrfyend{$testnum} = $timesrvrend{$testnum};
2789 $timesrvrlog{$testnum} = $timesrvrend{$testnum};
2790 $timetoolend{$testnum} = $timesrvrend{$testnum};
2791 $timetoolini{$testnum} = $timesrvrend{$testnum};
2793 elsif($timesrvrini{$testnum}) {
2794 $timevrfyend{$testnum} = $timesrvrini{$testnum};
2795 $timesrvrlog{$testnum} = $timesrvrini{$testnum};
2796 $timetoolend{$testnum} = $timesrvrini{$testnum};
2797 $timetoolini{$testnum} = $timesrvrini{$testnum};
2798 $timesrvrend{$testnum} = $timesrvrini{$testnum};
2800 elsif($timeprepini{$testnum}) {
2801 $timevrfyend{$testnum} = $timeprepini{$testnum};
2802 $timesrvrlog{$testnum} = $timeprepini{$testnum};
2803 $timetoolend{$testnum} = $timeprepini{$testnum};
2804 $timetoolini{$testnum} = $timeprepini{$testnum};
2805 $timesrvrend{$testnum} = $timeprepini{$testnum};
2806 $timesrvrini{$testnum} = $timeprepini{$testnum};
2811 #######################################################################
2812 # Run a single specified test case
2815 my ($evbased, # 1 means switch on if possible (and "curl" is tested)
2816 # returns "not a test" if it can't be used for this test
2825 my $disablevalgrind;
2827 # copy test number to a global scope var, this allows
2828 # testnum checking when starting test harness servers.
2829 $testnumcheck = $testnum;
2831 # timestamp test preparation start
2832 $timeprepini{$testnum} = Time::HiRes::time() if($timestats);
2834 if($disttests !~ /test$testnum\W/ ) {
2835 logmsg "Warning: test$testnum not present in tests/data/Makefile.inc\n";
2837 if($disabled{$testnum}) {
2838 logmsg "Warning: test$testnum is explicitly disabled\n";
2841 # load the test case file definition
2842 if(loadtest("${TESTDIR}/test${testnum}")) {
2844 # this is not a test
2845 logmsg "RUN: $testnum doesn't look like a test case\n";
2850 @what = getpart("client", "features");
2853 # We require a feature to be present
2858 if($f =~ /^([^!].*)$/) {
2859 # Store the feature for later
2867 elsif($1 eq "SSLpinning") {
2868 if($has_sslpinning) {
2872 elsif($1 eq "OpenSSL") {
2877 elsif($1 eq "GnuTLS") {
2882 elsif($1 eq "NSS") {
2887 elsif($1 eq "axTLS") {
2892 elsif($1 eq "WinSSL") {
2897 elsif($1 eq "DarwinSSL") {
2898 if($has_darwinssl) {
2902 elsif($1 eq "unittest") {
2907 elsif($1 eq "debug") {
2912 elsif($1 eq "TrackMemory") {
2913 if($has_memory_tracking) {
2917 elsif($1 eq "large_file") {
2918 if($has_largefile) {
2922 elsif($1 eq "idn") {
2927 elsif($1 eq "ipv6") {
2932 elsif($1 eq "libz") {
2937 elsif($1 eq "NTLM") {
2942 elsif($1 eq "NTLM_WB") {
2947 elsif($1 eq "SSPI") {
2952 elsif($1 eq "GSS-API") {
2957 elsif($1 eq "Kerberos") {
2962 elsif($1 eq "SPNEGO") {
2967 elsif($1 eq "getrlimit") {
2968 if($has_getrlimit) {
2972 elsif($1 eq "crypto") {
2977 elsif($1 eq "TLS-SRP") {
2982 elsif($1 eq "Metalink") {
2987 elsif($1 eq "http2") {
2992 elsif($1 eq "PSL") {
2997 elsif($1 eq "socks") {
3000 elsif($1 eq "unix-sockets") {
3003 # See if this "feature" is in the list of supported protocols
3004 elsif (grep /^\Q$1\E$/i, @protocols) {
3008 $why = "curl lacks $1 support";
3013 # We require a feature to not be present
3019 if($f =~ /^!(.*)$/) {
3025 elsif($1 eq "OpenSSL") {
3030 elsif($1 eq "GnuTLS") {
3035 elsif($1 eq "NSS") {
3040 elsif($1 eq "axTLS") {
3045 elsif($1 eq "WinSSL") {
3050 elsif($1 eq "DarwinSSL") {
3051 if(!$has_darwinssl) {
3055 elsif($1 eq "TrackMemory") {
3056 if(!$has_memory_tracking) {
3060 elsif($1 eq "large_file") {
3061 if(!$has_largefile) {
3065 elsif($1 eq "idn") {
3070 elsif($1 eq "ipv6") {
3075 elsif($1 eq "unix-sockets") {
3078 elsif($1 eq "libz") {
3083 elsif($1 eq "NTLM") {
3088 elsif($1 eq "NTLM_WB") {
3093 elsif($1 eq "SSPI") {
3098 elsif($1 eq "GSS-API") {
3103 elsif($1 eq "Kerberos") {
3104 if(!$has_kerberos) {
3108 elsif($1 eq "SPNEGO") {
3113 elsif($1 eq "getrlimit") {
3114 if(!$has_getrlimit) {
3118 elsif($1 eq "crypto") {
3123 elsif($1 eq "TLS-SRP") {
3128 elsif($1 eq "Metalink") {
3129 if(!$has_metalink) {
3133 elsif($1 eq "PSL") {
3146 $why = "curl has $1 support";
3152 my @keywords = getpart("info", "keywords");
3157 $why = "missing the <keywords> section!";
3160 for $k (@keywords) {
3162 if ($disabled_keywords{$k}) {
3163 $why = "disabled by keyword";
3164 } elsif ($enabled_keywords{$k}) {
3169 if(!$why && !$match && %enabled_keywords) {
3170 $why = "disabled by missing keyword";
3174 # test definition may instruct to (un)set environment vars
3175 # this is done this early, so that the precheck can use environment
3176 # variables and still bail out fine on errors
3178 # restore environment variables that were modified in a previous run
3179 foreach my $var (keys %oldenv) {
3180 if($oldenv{$var} eq 'notset') {
3181 delete $ENV{$var} if($ENV{$var});
3184 $ENV{$var} = $oldenv{$var};
3186 delete $oldenv{$var};
3189 # remove test server commands file before servers are started/verified
3190 unlink($FTPDCMD) if(-f $FTPDCMD);
3192 # timestamp required servers verification start
3193 $timesrvrini{$testnum} = Time::HiRes::time() if($timestats);
3196 $why = serverfortest($testnum);
3199 # timestamp required servers verification end
3200 $timesrvrend{$testnum} = Time::HiRes::time() if($timestats);
3202 my @setenv = getpart("client", "setenv");
3204 foreach my $s (@setenv) {
3207 if($s =~ /([^=]*)=(.*)/) {
3208 my ($var, $content) = ($1, $2);
3209 # remember current setting, to restore it once test runs
3210 $oldenv{$var} = ($ENV{$var})?"$ENV{$var}":'notset';
3213 delete $ENV{$var} if($ENV{$var});
3216 if($var =~ /^LD_PRELOAD/) {
3217 if(exe_ext() && (exe_ext() eq '.exe')) {
3218 # print "Skipping LD_PRELOAD due to lack of OS support\n";
3221 if($debug_build || ($has_shared ne "yes")) {
3222 # print "Skipping LD_PRELOAD due to no release shared build\n";
3226 $ENV{$var} = "$content";
3234 # Add a precheck cache. If a precheck command was already invoked
3235 # exactly like this, then use the previous result to speed up
3236 # successive test invokes!
3238 my @precheck = getpart("client", "precheck");
3240 $cmd = $precheck[0];
3244 my @p = split(/ /, $cmd);
3246 # the first word, the command, does not contain a slash so
3247 # we will scan the "improved" PATH to find the command to
3249 my $fullp = checktestcmd($p[0]);
3254 $cmd = join(" ", @p);
3257 my @o = `$cmd 2>/dev/null`;
3262 $why = "precheck command error";
3264 logmsg "prechecked $cmd\n" if($verbose);
3269 if($why && !$listonly) {
3270 # there's a problem, count it as "skipped"
3273 $teststat[$testnum]=$why; # store reason for this test case
3276 if($skipped{$why} <= 3) {
3277 # show only the first three skips for each reason
3278 logmsg sprintf("test %04d SKIPPED: $why\n", $testnum);
3282 timestampskippedevents($testnum);
3285 logmsg sprintf("test %04d...", $testnum) if(!$automakestyle);
3287 # extract the reply data
3288 my @reply = getpart("reply", "data");
3289 my @replycheck = getpart("reply", "datacheck");
3291 my %replyattr = getpartattr("reply", "data");
3292 my %replycheckattr = getpartattr("reply", "datacheck");
3295 # we use this file instead to check the final output against
3296 # get the mode attribute
3297 my $filemode=$replycheckattr{'mode'};
3298 if($filemode && ($filemode eq "text") && $has_textaware) {
3299 # text mode when running on windows: fix line endings
3300 map s/\r\n/\n/g, @replycheck;
3301 map s/\n/\r\n/g, @replycheck;
3303 if($replycheckattr{'nonewline'}) {
3304 # Yes, we must cut off the final newline from the final line
3306 chomp($replycheck[$#replycheck]);
3309 for my $partsuffix (('1', '2', '3', '4')) {
3310 my @replycheckpart = getpart("reply", "datacheck".$partsuffix);
3311 if(@replycheckpart || partexists("reply", "datacheck".$partsuffix) ) {
3312 my %replycheckpartattr = getpartattr("reply", "datacheck".$partsuffix);
3313 # get the mode attribute
3314 my $filemode=$replycheckpartattr{'mode'};
3315 if($filemode && ($filemode eq "text") && $has_textaware) {
3316 # text mode when running on windows: fix line endings
3317 map s/\r\n/\n/g, @replycheckpart;
3318 map s/\n/\r\n/g, @replycheckpart;
3320 if($replycheckpartattr{'nonewline'}) {
3321 # Yes, we must cut off the final newline from the final line
3323 chomp($replycheckpart[$#replycheckpart]);
3325 push(@replycheck, @replycheckpart);
3332 # get the mode attribute
3333 my $filemode=$replyattr{'mode'};
3334 if($filemode && ($filemode eq "text") && $has_textaware) {
3335 # text mode when running on windows: fix line endings
3336 map s/\r\n/\n/g, @reply;
3337 map s/\n/\r\n/g, @reply;
3341 # this is the valid protocol blurb curl should generate
3342 my @protocol= fixarray ( getpart("verify", "protocol") );
3344 # this is the valid protocol blurb curl should generate to a proxy
3345 my @proxyprot = fixarray ( getpart("verify", "proxy") );
3347 # redirected stdout/stderr to these files
3348 $STDOUT="$LOGDIR/stdout$testnum";
3349 $STDERR="$LOGDIR/stderr$testnum";
3351 # if this section exists, we verify that the stdout contained this:
3352 my @validstdout = fixarray ( getpart("verify", "stdout") );
3354 # if this section exists, we verify upload
3355 my @upload = getpart("verify", "upload");
3357 # if this section exists, it might be FTP server instructions:
3358 my @ftpservercmd = getpart("reply", "servercmd");
3360 my $CURLOUT="$LOGDIR/curl$testnum.out"; # curl output if not stdout
3363 my @testname= getpart("client", "name");
3364 my $testname = $testname[0];
3365 $testname =~ s/\n//g;
3366 logmsg "[$testname]\n" if(!$short);
3369 timestampskippedevents($testnum);
3370 return 0; # look successful
3373 my @codepieces = getpart("client", "tool");
3377 $tool = $codepieces[0];
3381 # remove server output logfile
3387 # write the instructions to file
3388 writearray($FTPDCMD, \@ftpservercmd);
3391 # get the command line options to use
3393 ($cmd, @blaha)= getpart("client", "command");
3396 # make some nice replace operations
3397 $cmd =~ s/\n//g; # no newlines please
3398 # substitute variables in the command line
3402 # there was no command given, use something silly
3405 if($has_memory_tracking) {
3409 # create a (possibly-empty) file before starting the test
3410 my @inputfile=getpart("client", "file");
3411 my %fileattr = getpartattr("client", "file");
3412 my $filename=$fileattr{'name'};
3413 if(@inputfile || $filename) {
3415 logmsg "ERROR: section client=>file has no name attribute\n";
3416 timestampskippedevents($testnum);
3419 my $fileContent = join('', @inputfile);
3420 subVariables \$fileContent;
3421 # logmsg "DEBUG: writing file " . $filename . "\n";
3422 open(OUTFILE, ">$filename");
3423 binmode OUTFILE; # for crapage systems, use binary
3424 print OUTFILE $fileContent;
3428 my %cmdhash = getpartattr("client", "command");
3432 if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-output/)) {
3433 #We may slap on --output!
3434 if (!@validstdout) {
3435 $out=" --output $CURLOUT ";
3439 my $serverlogslocktimeout = $defserverlogslocktimeout;
3440 if($cmdhash{'timeout'}) {
3441 # test is allowed to override default server logs lock timeout
3442 if($cmdhash{'timeout'} =~ /(\d+)/) {
3443 $serverlogslocktimeout = $1 if($1 >= 0);
3447 my $postcommanddelay = $defpostcommanddelay;
3448 if($cmdhash{'delay'}) {
3449 # test is allowed to specify a delay after command is executed
3450 if($cmdhash{'delay'} =~ /(\d+)/) {
3451 $postcommanddelay = $1 if($1 > 0);
3457 my $cmdtype = $cmdhash{'type'} || "default";
3458 my $fail_due_event_based = $evbased;
3459 if($cmdtype eq "perl") {
3460 # run the command line prepended with "perl"
3466 elsif($cmdtype eq "shell") {
3467 # run the command line prepended with "/bin/sh"
3469 $CMDLINE = "/bin/sh ";
3474 # run curl, add suitable command line options
3475 $cmd = "-1 ".$cmd if(exists $feature{"SSL"} && ($has_axtls));
3478 if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-include/)) {
3479 $inc = " --include";
3482 $cmdargs = "$out$inc ";
3483 $cmdargs .= "--trace-ascii log/trace$testnum ";
3484 $cmdargs .= "--trace-time ";
3486 $cmdargs .= "--test-event ";
3487 $fail_due_event_based--;
3492 $cmdargs = " $cmd"; # $cmd is the command line for the test file
3493 $CURLOUT = $STDOUT; # sends received data to stdout
3495 if($tool =~ /^lib/) {
3496 $CMDLINE="$LIBDIR/$tool";
3498 elsif($tool =~ /^unit/) {
3499 $CMDLINE="$UNITDIR/$tool";
3503 logmsg "The tool set in the test case for this: '$tool' does not exist\n";
3504 timestampskippedevents($testnum);
3511 # gdb is incompatible with valgrind, so disable it when debugging
3512 # Perhaps a better approach would be to run it under valgrind anyway
3513 # with --db-attach=yes or --vgdb=yes.
3517 if($fail_due_event_based) {
3518 logmsg "This test cannot run event based\n";
3522 my @stdintest = getpart("client", "stdin");
3525 my $stdinfile="$LOGDIR/stdin-for-$testnum";
3527 my %hash = getpartattr("client", "stdin");
3528 if($hash{'nonewline'}) {
3529 # cut off the final newline from the final line of the stdin data
3530 chomp($stdintest[$#stdintest]);
3533 writearray($stdinfile, \@stdintest);
3535 $cmdargs .= " <$stdinfile";
3543 if($valgrind && !$disablevalgrind) {
3544 my @valgrindoption = getpart("verify", "valgrind");
3545 if((!@valgrindoption) || ($valgrindoption[0] !~ /disable/)) {
3547 my $valgrindcmd = "$valgrind ";
3548 $valgrindcmd .= "$valgrind_tool " if($valgrind_tool);
3549 $valgrindcmd .= "--leak-check=yes ";
3550 $valgrindcmd .= "--suppressions=$srcdir/valgrind.supp ";
3551 # $valgrindcmd .= "--gen-suppressions=all ";
3552 $valgrindcmd .= "--num-callers=16 ";
3553 $valgrindcmd .= "${valgrind_logfile}=$LOGDIR/valgrind$testnum";
3554 $CMDLINE = "$valgrindcmd $CMDLINE";
3558 $CMDLINE .= "$cmdargs >$STDOUT 2>$STDERR";
3561 logmsg "$CMDLINE\n";
3564 print CMDLOG "$CMDLINE\n";
3571 # Apr 2007: precommand isn't being used and could be removed
3572 my @precommand= getpart("client", "precommand");
3573 if($precommand[0]) {
3574 # this is pure perl to eval!
3575 my $code = join("", @precommand);
3578 logmsg "perl: $code\n";
3579 logmsg "precommand: $@";
3580 stopservers($verbose);
3581 timestampskippedevents($testnum);
3587 my $gdbinit = "$TESTDIR/gdbinit$testnum";
3588 open(GDBCMD, ">$LOGDIR/gdbcmd");
3589 print GDBCMD "set args $cmdargs\n";
3590 print GDBCMD "show args\n";
3591 print GDBCMD "source $gdbinit\n" if -e $gdbinit;
3595 # timestamp starting of test command
3596 $timetoolini{$testnum} = Time::HiRes::time() if($timestats);
3598 # run the command line we built
3600 $cmdres = torture($CMDLINE,
3601 "$gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
3604 my $GDBW = ($gdbxwin) ? "-w" : "";
3605 runclient("$gdb --directory libtest $DBGCURL $GDBW -x $LOGDIR/gdbcmd");
3606 $cmdres=0; # makes it always continue after a debugged run
3609 $cmdres = runclient("$CMDLINE");
3610 my $signal_num = $cmdres & 127;
3611 $dumped_core = $cmdres & 128;
3613 if(!$anyway && ($signal_num || $dumped_core)) {
3618 $cmdres = (2000 + $signal_num) if($signal_num && !$cmdres);
3622 # timestamp finishing of test command
3623 $timetoolend{$testnum} = Time::HiRes::time() if($timestats);
3627 # there's core file present now!
3633 logmsg "core dumped\n";
3635 logmsg "running gdb for post-mortem analysis:\n";
3636 open(GDBCMD, ">$LOGDIR/gdbcmd2");
3637 print GDBCMD "bt\n";
3639 runclient("$gdb --directory libtest -x $LOGDIR/gdbcmd2 -batch $DBGCURL core ");
3640 # unlink("$LOGDIR/gdbcmd2");
3644 # If a server logs advisor read lock file exists, it is an indication
3645 # that the server has not yet finished writing out all its log files,
3646 # including server request log files used for protocol verification.
3647 # So, if the lock file exists the script waits here a certain amount
3648 # of time until the server removes it, or the given time expires.
3650 if($serverlogslocktimeout) {
3651 my $lockretry = $serverlogslocktimeout * 20;
3652 while((-f $SERVERLOGS_LOCK) && $lockretry--) {
3653 select(undef, undef, undef, 0.05);
3655 if(($lockretry < 0) &&
3656 ($serverlogslocktimeout >= $defserverlogslocktimeout)) {
3657 logmsg "Warning: server logs lock timeout ",
3658 "($serverlogslocktimeout seconds) expired\n";
3662 # Test harness ssh server does not have this synchronization mechanism,
3663 # this implies that some ssh server based tests might need a small delay
3664 # once that the client command has run to avoid false test failures.
3666 # gnutls-serv also lacks this synchronization mechanism, so gnutls-serv
3667 # based tests might need a small delay once that the client command has
3668 # run to avoid false test failures.
3670 sleep($postcommanddelay) if($postcommanddelay);
3672 # timestamp removal of server logs advisor read lock
3673 $timesrvrlog{$testnum} = Time::HiRes::time() if($timestats);
3675 # test definition might instruct to stop some servers
3676 # stop also all servers relative to the given one
3678 my @killtestservers = getpart("client", "killserver");
3679 if(@killtestservers) {
3681 # All servers relative to the given one must be stopped also
3684 foreach my $server (@killtestservers) {
3686 if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
3687 # given a stunnel ssl server, also kill non-ssl underlying one
3688 push @killservers, "${1}${2}";
3690 elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|-unix|))$/) {
3691 # given a non-ssl server, also kill stunnel piggybacking one
3692 push @killservers, "${1}s${2}";
3694 elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
3695 # given a socks server, also kill ssh underlying one
3696 push @killservers, "ssh${2}";
3698 elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
3699 # given a ssh server, also kill socks piggybacking one
3700 push @killservers, "socks${2}";
3702 push @killservers, $server;
3705 # kill sockfilter processes for pingpong relative servers
3707 foreach my $server (@killservers) {
3708 if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
3710 my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
3711 my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
3712 killsockfilters($proto, $ipvnum, $idnum, $verbose);
3716 # kill server relative pids clearing them in %run hash
3719 foreach my $server (@killservers) {
3721 $pidlist .= "$run{$server} ";
3724 $runcert{$server} = 0 if($runcert{$server});
3726 killpid($verbose, $pidlist);
3728 # cleanup server pid files
3730 foreach my $server (@killservers) {
3731 my $pidfile = $serverpidfile{$server};
3732 my $pid = processexists($pidfile);
3734 logmsg "Warning: $server server unexpectedly alive\n";
3735 killpid($verbose, $pid);
3737 unlink($pidfile) if(-f $pidfile);
3741 # remove the test server commands file after each test
3742 unlink($FTPDCMD) if(-f $FTPDCMD);
3744 # run the postcheck command
3745 my @postcheck= getpart("client", "postcheck");
3747 $cmd = $postcheck[0];
3751 logmsg "postcheck $cmd\n" if($verbose);
3752 my $rc = runclient("$cmd");
3753 # Must run the postcheck command in torture mode in order
3754 # to clean up, but the result can't be relied upon.
3755 if($rc != 0 && !$torture) {
3756 logmsg " postcheck FAILED\n";
3757 # timestamp test result verification end
3758 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3764 # restore environment variables that were modified
3766 foreach my $var (keys %oldenv) {
3767 if($oldenv{$var} eq 'notset') {
3768 delete $ENV{$var} if($ENV{$var});
3771 $ENV{$var} = "$oldenv{$var}";
3776 # Skip all the verification on torture tests
3778 if(!$cmdres && !$keepoutfiles) {
3781 # timestamp test result verification end
3782 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3786 my @err = getpart("verify", "errorcode");
3787 my $errorcode = $err[0] || "0";
3792 # verify redirected stdout
3793 my @actual = loadarray($STDOUT);
3795 # variable-replace in the stdout we have from the test case file
3796 @validstdout = fixarray(@validstdout);
3798 # get all attributes
3799 my %hash = getpartattr("verify", "stdout");
3801 # get the mode attribute
3802 my $filemode=$hash{'mode'};
3803 if($filemode && ($filemode eq "text") && $has_textaware) {
3804 # text mode when running on windows: fix line endings
3805 map s/\r\n/\n/g, @validstdout;
3806 map s/\n/\r\n/g, @validstdout;
3809 if($hash{'nonewline'}) {
3810 # Yes, we must cut off the final newline from the final line
3811 # of the protocol data
3812 chomp($validstdout[$#validstdout]);
3815 $res = compare($testnum, $testname, "stdout", \@actual, \@validstdout);
3822 $ok .= "-"; # stdout not checked
3826 # Verify the sent request
3827 my @out = loadarray($SERVERIN);
3829 # what to cut off from the live protocol sent by curl
3830 my @strip = getpart("verify", "strip");
3832 my @protstrip=@protocol;
3834 # check if there's any attributes on the verify/protocol section
3835 my %hash = getpartattr("verify", "protocol");
3837 if($hash{'nonewline'}) {
3838 # Yes, we must cut off the final newline from the final line
3839 # of the protocol data
3840 chomp($protstrip[$#protstrip]);
3844 # strip off all lines that match the patterns from both arrays
3846 @out = striparray( $_, \@out);
3847 @protstrip= striparray( $_, \@protstrip);
3850 # what parts to cut off from the protocol
3851 my @strippart = getpart("verify", "strippart");
3853 for $strip (@strippart) {
3860 $res = compare($testnum, $testname, "protocol", \@out, \@protstrip);
3869 $ok .= "-"; # protocol not checked
3872 if(!$replyattr{'nocheck'} && (@reply || $replyattr{'sendzero'})) {
3873 # verify the received data
3874 my @out = loadarray($CURLOUT);
3875 $res = compare($testnum, $testname, "data", \@out, \@reply);
3882 $ok .= "-"; # data not checked
3886 # verify uploaded data
3887 my @out = loadarray("$LOGDIR/upload.$testnum");
3888 $res = compare($testnum, $testname, "upload", \@out, \@upload);
3895 $ok .= "-"; # upload not checked
3899 # Verify the sent proxy request
3900 my @out = loadarray($PROXYIN);
3902 # what to cut off from the live protocol sent by curl, we use the
3903 # same rules as for <protocol>
3904 my @strip = getpart("verify", "strip");
3906 my @protstrip=@proxyprot;
3908 # check if there's any attributes on the verify/protocol section
3909 my %hash = getpartattr("verify", "proxy");
3911 if($hash{'nonewline'}) {
3912 # Yes, we must cut off the final newline from the final line
3913 # of the protocol data
3914 chomp($protstrip[$#protstrip]);
3918 # strip off all lines that match the patterns from both arrays
3920 @out = striparray( $_, \@out);
3921 @protstrip= striparray( $_, \@protstrip);
3924 # what parts to cut off from the protocol
3925 my @strippart = getpart("verify", "strippart");
3927 for $strip (@strippart) {
3934 $res = compare($testnum, $testname, "proxy", \@out, \@protstrip);
3943 $ok .= "-"; # protocol not checked
3947 for my $partsuffix (('', '1', '2', '3', '4')) {
3948 my @outfile=getpart("verify", "file".$partsuffix);
3949 if(@outfile || partexists("verify", "file".$partsuffix) ) {
3950 # we're supposed to verify a dynamically generated file!
3951 my %hash = getpartattr("verify", "file".$partsuffix);
3953 my $filename=$hash{'name'};
3955 logmsg "ERROR: section verify=>file$partsuffix ".
3956 "has no name attribute\n";
3957 stopservers($verbose);
3958 # timestamp test result verification end
3959 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
3962 my @generated=loadarray($filename);
3964 # what parts to cut off from the file
3965 my @stripfile = getpart("verify", "stripfile".$partsuffix);
3967 my $filemode=$hash{'mode'};
3968 if($filemode && ($filemode eq "text") && $has_textaware) {
3969 # text mode when running on windows: fix line endings
3970 map s/\r\n/\n/g, @outfile;
3971 map s/\n/\r\n/g, @outfile;
3975 for $strip (@stripfile) {
3984 # this is to get rid of array entries that vanished (zero
3985 # length) because of replacements
3986 @generated = @newgen;
3989 @outfile = fixarray(@outfile);
3991 $res = compare($testnum, $testname, "output ($filename)",
3992 \@generated, \@outfile);
3997 $outputok = 1; # output checked
4000 $ok .= ($outputok) ? "o" : "-"; # output checked or not
4002 # accept multiple comma-separated error codes
4003 my @splerr = split(/ *, */, $errorcode);
4005 foreach my $e (@splerr) {
4018 logmsg sprintf("\n%s returned $cmdres, when expecting %s\n",
4019 (!$tool)?"curl":$tool, $errorcode);
4021 logmsg " exit FAILED\n";
4022 # timestamp test result verification end
4023 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
4027 if($has_memory_tracking) {
4029 logmsg "\n** ALERT! memory tracking with no output file?\n"
4030 if(!$cmdtype eq "perl");
4033 my @memdata=`$memanalyze $memdump`;
4037 # well it could be other memory problems as well, but
4038 # we call it leak for short here
4043 logmsg "\n** MEMORY FAILURE\n";
4045 # timestamp test result verification end
4046 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
4055 $ok .= "-"; # memory not checked
4060 unless(opendir(DIR, "$LOGDIR")) {
4061 logmsg "ERROR: unable to read $LOGDIR\n";
4062 # timestamp test result verification end
4063 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
4066 my @files = readdir(DIR);
4069 foreach my $file (@files) {
4070 if($file =~ /^valgrind$testnum(\..*|)$/) {
4076 logmsg "ERROR: valgrind log file missing for test $testnum\n";
4077 # timestamp test result verification end
4078 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
4081 my @e = valgrindparse($srcdir, $feature{'SSL'}, "$LOGDIR/$vgfile");
4083 if($automakestyle) {
4084 logmsg "FAIL: $testnum - $testname - valgrind\n";
4087 logmsg " valgrind ERROR ";
4090 # timestamp test result verification end
4091 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
4097 if(!$short && !$disablevalgrind) {
4098 logmsg " valgrind SKIPPED\n";
4100 $ok .= "-"; # skipped
4104 $ok .= "-"; # valgrind not checked
4106 # add 'E' for event-based
4107 $ok .= $evbased ? "E" : "-";
4109 logmsg "$ok " if(!$short);
4111 my $sofar= time()-$start;
4112 my $esttotal = $sofar/$count * $total;
4113 my $estleft = $esttotal - $sofar;
4114 my $left=sprintf("remaining: %02d:%02d",
4118 if(!$automakestyle) {
4119 logmsg sprintf("OK (%-3d out of %-3d, %s)\n", $count, $total, $left);
4122 logmsg "PASS: $testnum - $testname\n";
4125 # the test succeeded, remove all log files
4126 if(!$keepoutfiles) {
4130 # timestamp test result verification end
4131 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
4136 #######################################################################
4137 # Stop all running test servers
4140 my $verbose = $_[0];
4142 # kill sockfilter processes for all pingpong servers
4144 killallsockfilters($verbose);
4146 # kill all server pids from %run hash clearing them
4149 foreach my $server (keys %run) {
4153 my $pids = $run{$server};
4154 foreach my $pid (split(' ', $pids)) {
4156 logmsg sprintf("* kill pid for %s => %d\n",
4162 $pidlist .= "$run{$server} ";
4165 $runcert{$server} = 0 if($runcert{$server});
4167 killpid($verbose, $pidlist);
4169 # cleanup all server pid files
4171 foreach my $server (keys %serverpidfile) {
4172 my $pidfile = $serverpidfile{$server};
4173 my $pid = processexists($pidfile);
4175 logmsg "Warning: $server server unexpectedly alive\n";
4176 killpid($verbose, $pid);
4178 unlink($pidfile) if(-f $pidfile);
4182 #######################################################################
4183 # startservers() starts all the named servers
4185 # Returns: string with error reason or blank for success
4191 my (@whatlist) = split(/\s+/,$_);
4192 my $what = lc($whatlist[0]);
4193 $what =~ s/[^a-z0-9-]//g;
4196 if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
4197 $certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem';
4200 if(($what eq "pop3") ||
4202 ($what eq "imap") ||
4203 ($what eq "smtp")) {
4204 if($torture && $run{$what} &&
4205 !responsive_pingpong_server($what, "", $verbose)) {
4209 ($pid, $pid2) = runpingpongserver($what, "", $verbose);
4211 return "failed starting ". uc($what) ." server";
4213 printf ("* pid $what => %d %d\n", $pid, $pid2) if($verbose);
4214 $run{$what}="$pid $pid2";
4217 elsif($what eq "ftp2") {
4218 if($torture && $run{'ftp2'} &&
4219 !responsive_pingpong_server("ftp", "2", $verbose)) {
4223 ($pid, $pid2) = runpingpongserver("ftp", "2", $verbose);
4225 return "failed starting FTP2 server";
4227 printf ("* pid ftp2 => %d %d\n", $pid, $pid2) if($verbose);
4228 $run{'ftp2'}="$pid $pid2";
4231 elsif($what eq "ftp-ipv6") {
4232 if($torture && $run{'ftp-ipv6'} &&
4233 !responsive_pingpong_server("ftp", "", $verbose, "ipv6")) {
4234 stopserver('ftp-ipv6');
4236 if(!$run{'ftp-ipv6'}) {
4237 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose, "ipv6");
4239 return "failed starting FTP-IPv6 server";
4241 logmsg sprintf("* pid ftp-ipv6 => %d %d\n", $pid,
4242 $pid2) if($verbose);
4243 $run{'ftp-ipv6'}="$pid $pid2";
4246 elsif($what eq "gopher") {
4247 if($torture && $run{'gopher'} &&
4248 !responsive_http_server("gopher", $verbose, 0, $GOPHERPORT)) {
4249 stopserver('gopher');
4251 if(!$run{'gopher'}) {
4252 ($pid, $pid2) = runhttpserver("gopher", $verbose, 0,
4255 return "failed starting GOPHER server";
4257 logmsg sprintf ("* pid gopher => %d %d\n", $pid, $pid2)
4259 $run{'gopher'}="$pid $pid2";
4262 elsif($what eq "gopher-ipv6") {
4263 if($torture && $run{'gopher-ipv6'} &&
4264 !responsive_http_server("gopher", $verbose, "ipv6",
4266 stopserver('gopher-ipv6');
4268 if(!$run{'gopher-ipv6'}) {
4269 ($pid, $pid2) = runhttpserver("gopher", $verbose, "ipv6",
4272 return "failed starting GOPHER-IPv6 server";
4274 logmsg sprintf("* pid gopher-ipv6 => %d %d\n", $pid,
4275 $pid2) if($verbose);
4276 $run{'gopher-ipv6'}="$pid $pid2";
4279 elsif($what eq "http") {
4280 if($torture && $run{'http'} &&
4281 !responsive_http_server("http", $verbose, 0, $HTTPPORT)) {
4285 ($pid, $pid2) = runhttpserver("http", $verbose, 0,
4288 return "failed starting HTTP server";
4290 logmsg sprintf ("* pid http => %d %d\n", $pid, $pid2)
4292 $run{'http'}="$pid $pid2";
4295 elsif($what eq "http-proxy") {
4296 if($torture && $run{'http-proxy'} &&
4297 !responsive_http_server("http", $verbose, "proxy",
4299 stopserver('http-proxy');
4301 if(!$run{'http-proxy'}) {
4302 ($pid, $pid2) = runhttpserver("http", $verbose, "proxy",
4305 return "failed starting HTTP-proxy server";
4307 logmsg sprintf ("* pid http-proxy => %d %d\n", $pid, $pid2)
4309 $run{'http-proxy'}="$pid $pid2";
4312 elsif($what eq "http-ipv6") {
4313 if($torture && $run{'http-ipv6'} &&
4314 !responsive_http_server("http", $verbose, "ipv6", $HTTP6PORT)) {
4315 stopserver('http-ipv6');
4317 if(!$run{'http-ipv6'}) {
4318 ($pid, $pid2) = runhttpserver("http", $verbose, "ipv6",
4321 return "failed starting HTTP-IPv6 server";
4323 logmsg sprintf("* pid http-ipv6 => %d %d\n", $pid, $pid2)
4325 $run{'http-ipv6'}="$pid $pid2";
4328 elsif($what eq "http-pipe") {
4329 if($torture && $run{'http-pipe'} &&
4330 !responsive_http_server("http", $verbose, "pipe",
4332 stopserver('http-pipe');
4334 if(!$run{'http-pipe'}) {
4335 ($pid, $pid2) = runhttpserver("http", $verbose, "pipe",
4338 return "failed starting HTTP-pipe server";
4340 logmsg sprintf ("* pid http-pipe => %d %d\n", $pid, $pid2)
4342 $run{'http-pipe'}="$pid $pid2";
4345 elsif($what eq "rtsp") {
4346 if($torture && $run{'rtsp'} &&
4347 !responsive_rtsp_server($verbose)) {
4351 ($pid, $pid2) = runrtspserver($verbose);
4353 return "failed starting RTSP server";
4355 printf ("* pid rtsp => %d %d\n", $pid, $pid2) if($verbose);
4356 $run{'rtsp'}="$pid $pid2";
4359 elsif($what eq "rtsp-ipv6") {
4360 if($torture && $run{'rtsp-ipv6'} &&
4361 !responsive_rtsp_server($verbose, "ipv6")) {
4362 stopserver('rtsp-ipv6');
4364 if(!$run{'rtsp-ipv6'}) {
4365 ($pid, $pid2) = runrtspserver($verbose, "ipv6");
4367 return "failed starting RTSP-IPv6 server";
4369 logmsg sprintf("* pid rtsp-ipv6 => %d %d\n", $pid, $pid2)
4371 $run{'rtsp-ipv6'}="$pid $pid2";
4374 elsif($what eq "ftps") {
4376 # we can't run ftps tests without stunnel
4377 return "no stunnel";
4380 # we can't run ftps tests if libcurl is SSL-less
4381 return "curl lacks SSL support";
4383 if($runcert{'ftps'} && ($runcert{'ftps'} ne $certfile)) {
4384 # stop server when running and using a different cert
4387 if($torture && $run{'ftp'} &&
4388 !responsive_pingpong_server("ftp", "", $verbose)) {
4392 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose);
4394 return "failed starting FTP server";
4396 printf ("* pid ftp => %d %d\n", $pid, $pid2) if($verbose);
4397 $run{'ftp'}="$pid $pid2";
4400 ($pid, $pid2) = runftpsserver($verbose, "", $certfile);
4402 return "failed starting FTPS server (stunnel)";
4404 logmsg sprintf("* pid ftps => %d %d\n", $pid, $pid2)
4406 $run{'ftps'}="$pid $pid2";
4409 elsif($what eq "file") {
4410 # we support it but have no server!
4412 elsif($what eq "https") {
4414 # we can't run https tests without stunnel
4415 return "no stunnel";
4418 # we can't run https tests if libcurl is SSL-less
4419 return "curl lacks SSL support";
4421 if($runcert{'https'} && ($runcert{'https'} ne $certfile)) {
4422 # stop server when running and using a different cert
4423 stopserver('https');
4425 if($torture && $run{'http'} &&
4426 !responsive_http_server("http", $verbose, 0, $HTTPPORT)) {
4430 ($pid, $pid2) = runhttpserver("http", $verbose, 0,
4433 return "failed starting HTTP server";
4435 printf ("* pid http => %d %d\n", $pid, $pid2) if($verbose);
4436 $run{'http'}="$pid $pid2";
4438 if(!$run{'https'}) {
4439 ($pid, $pid2) = runhttpsserver($verbose, "", $certfile);
4441 return "failed starting HTTPS server (stunnel)";
4443 logmsg sprintf("* pid https => %d %d\n", $pid, $pid2)
4445 $run{'https'}="$pid $pid2";
4448 elsif($what eq "httptls") {
4450 # for now, we can't run http TLS-EXT tests without gnutls-serv
4451 return "no gnutls-serv";
4453 if($torture && $run{'httptls'} &&
4454 !responsive_httptls_server($verbose, "IPv4")) {
4455 stopserver('httptls');
4457 if(!$run{'httptls'}) {
4458 ($pid, $pid2) = runhttptlsserver($verbose, "IPv4");
4460 return "failed starting HTTPTLS server (gnutls-serv)";
4462 logmsg sprintf("* pid httptls => %d %d\n", $pid, $pid2)
4464 $run{'httptls'}="$pid $pid2";
4467 elsif($what eq "httptls-ipv6") {
4469 # for now, we can't run http TLS-EXT tests without gnutls-serv
4470 return "no gnutls-serv";
4472 if($torture && $run{'httptls-ipv6'} &&
4473 !responsive_httptls_server($verbose, "ipv6")) {
4474 stopserver('httptls-ipv6');
4476 if(!$run{'httptls-ipv6'}) {
4477 ($pid, $pid2) = runhttptlsserver($verbose, "ipv6");
4479 return "failed starting HTTPTLS-IPv6 server (gnutls-serv)";
4481 logmsg sprintf("* pid httptls-ipv6 => %d %d\n", $pid, $pid2)
4483 $run{'httptls-ipv6'}="$pid $pid2";
4486 elsif($what eq "tftp") {
4487 if($torture && $run{'tftp'} &&
4488 !responsive_tftp_server("", $verbose)) {
4492 ($pid, $pid2) = runtftpserver("", $verbose);
4494 return "failed starting TFTP server";
4496 printf ("* pid tftp => %d %d\n", $pid, $pid2) if($verbose);
4497 $run{'tftp'}="$pid $pid2";
4500 elsif($what eq "tftp-ipv6") {
4501 if($torture && $run{'tftp-ipv6'} &&
4502 !responsive_tftp_server("", $verbose, "ipv6")) {
4503 stopserver('tftp-ipv6');
4505 if(!$run{'tftp-ipv6'}) {
4506 ($pid, $pid2) = runtftpserver("", $verbose, "ipv6");
4508 return "failed starting TFTP-IPv6 server";
4510 printf("* pid tftp-ipv6 => %d %d\n", $pid, $pid2) if($verbose);
4511 $run{'tftp-ipv6'}="$pid $pid2";
4514 elsif($what eq "sftp" || $what eq "scp" || $what eq "socks4" || $what eq "socks5" ) {
4516 ($pid, $pid2) = runsshserver("", $verbose);
4518 return "failed starting SSH server";
4520 printf ("* pid ssh => %d %d\n", $pid, $pid2) if($verbose);
4521 $run{'ssh'}="$pid $pid2";
4523 if($what eq "socks4" || $what eq "socks5") {
4524 if(!$run{'socks'}) {
4525 ($pid, $pid2) = runsocksserver("", $verbose);
4527 return "failed starting socks server";
4529 printf ("* pid socks => %d %d\n", $pid, $pid2) if($verbose);
4530 $run{'socks'}="$pid $pid2";
4533 if($what eq "socks5") {
4535 # Not an OpenSSH or SunSSH ssh daemon
4536 logmsg "Not OpenSSH or SunSSH; socks5 tests need at least OpenSSH 3.7\n";
4537 return "failed starting socks5 server";
4539 elsif(($sshdid =~ /OpenSSH/) && ($sshdvernum < 370)) {
4540 # Need OpenSSH 3.7 for socks5 - http://www.openssh.com/txt/release-3.7
4541 logmsg "$sshdverstr insufficient; socks5 tests need at least OpenSSH 3.7\n";
4542 return "failed starting socks5 server";
4544 elsif(($sshdid =~ /SunSSH/) && ($sshdvernum < 100)) {
4545 # Need SunSSH 1.0 for socks5
4546 logmsg "$sshdverstr insufficient; socks5 tests need at least SunSSH 1.0\n";
4547 return "failed starting socks5 server";
4551 elsif($what eq "http-unix") {
4552 if($torture && $run{'http-unix'} &&
4553 !responsive_http_server("http", $verbose, "unix", $HTTPUNIXPATH)) {
4554 stopserver('http-unix');
4556 if(!$run{'http-unix'}) {
4557 ($pid, $pid2) = runhttpserver("http", $verbose, "unix",
4560 return "failed starting HTTP-unix server";
4562 logmsg sprintf("* pid http-unix => %d %d\n", $pid, $pid2)
4564 $run{'http-unix'}="$pid $pid2";
4567 elsif($what eq "none") {
4568 logmsg "* starts no server\n" if ($verbose);
4571 warn "we don't support a server for $what";
4572 return "no server for $what";
4578 ##############################################################################
4579 # This function makes sure the right set of server is running for the
4580 # specified test case. This is a useful design when we run single tests as not
4581 # all servers need to run then!
4583 # Returns: a string, blank if everything is fine or a reason why it failed
4588 my @what = getpart("client", "server");
4591 warn "Test case $testnum has no server(s) specified";
4592 return "no server specified";
4595 for(my $i = scalar(@what) - 1; $i >= 0; $i--) {
4596 my $srvrline = $what[$i];
4597 chomp $srvrline if($srvrline);
4598 if($srvrline =~ /^(\S+)((\s*)(.*))/) {
4599 my $server = "${1}";
4600 my $lnrest = "${2}";
4602 if($server =~ /^(httptls)(\+)(ext|srp)(\d*)(-ipv6|)$/) {
4603 $server = "${1}${4}${5}";
4604 $tlsext = uc("TLS-${3}");
4606 if(! grep /^\Q$server\E$/, @protocols) {
4607 if(substr($server,0,5) ne "socks") {
4609 return "curl lacks $tlsext support";
4612 return "curl lacks $server server support";
4616 $what[$i] = "$server$lnrest" if($tlsext);
4620 return &startservers(@what);
4623 #######################################################################
4624 # runtimestats displays test-suite run time statistics
4627 my $lasttest = $_[0];
4629 return if(not $timestats);
4631 logmsg "\nTest suite total running time breakdown per task...\n\n";
4639 my $timesrvrtot = 0.0;
4640 my $timepreptot = 0.0;
4641 my $timetooltot = 0.0;
4642 my $timelocktot = 0.0;
4643 my $timevrfytot = 0.0;
4644 my $timetesttot = 0.0;
4647 for my $testnum (1 .. $lasttest) {
4648 if($timesrvrini{$testnum}) {
4649 $timesrvrtot += $timesrvrend{$testnum} - $timesrvrini{$testnum};
4651 (($timetoolini{$testnum} - $timeprepini{$testnum}) -
4652 ($timesrvrend{$testnum} - $timesrvrini{$testnum}));
4653 $timetooltot += $timetoolend{$testnum} - $timetoolini{$testnum};
4654 $timelocktot += $timesrvrlog{$testnum} - $timetoolend{$testnum};
4655 $timevrfytot += $timevrfyend{$testnum} - $timesrvrlog{$testnum};
4656 $timetesttot += $timevrfyend{$testnum} - $timeprepini{$testnum};
4657 push @timesrvr, sprintf("%06.3f %04d",
4658 $timesrvrend{$testnum} - $timesrvrini{$testnum}, $testnum);
4659 push @timeprep, sprintf("%06.3f %04d",
4660 ($timetoolini{$testnum} - $timeprepini{$testnum}) -
4661 ($timesrvrend{$testnum} - $timesrvrini{$testnum}), $testnum);
4662 push @timetool, sprintf("%06.3f %04d",
4663 $timetoolend{$testnum} - $timetoolini{$testnum}, $testnum);
4664 push @timelock, sprintf("%06.3f %04d",
4665 $timesrvrlog{$testnum} - $timetoolend{$testnum}, $testnum);
4666 push @timevrfy, sprintf("%06.3f %04d",
4667 $timevrfyend{$testnum} - $timesrvrlog{$testnum}, $testnum);
4668 push @timetest, sprintf("%06.3f %04d",
4669 $timevrfyend{$testnum} - $timeprepini{$testnum}, $testnum);
4674 no warnings 'numeric';
4675 @timesrvr = sort { $b <=> $a } @timesrvr;
4676 @timeprep = sort { $b <=> $a } @timeprep;
4677 @timetool = sort { $b <=> $a } @timetool;
4678 @timelock = sort { $b <=> $a } @timelock;
4679 @timevrfy = sort { $b <=> $a } @timevrfy;
4680 @timetest = sort { $b <=> $a } @timetest;
4683 logmsg "Spent ". sprintf("%08.3f ", $timesrvrtot) .
4684 "seconds starting and verifying test harness servers.\n";
4685 logmsg "Spent ". sprintf("%08.3f ", $timepreptot) .
4686 "seconds reading definitions and doing test preparations.\n";
4687 logmsg "Spent ". sprintf("%08.3f ", $timetooltot) .
4688 "seconds actually running test tools.\n";
4689 logmsg "Spent ". sprintf("%08.3f ", $timelocktot) .
4690 "seconds awaiting server logs lock removal.\n";
4691 logmsg "Spent ". sprintf("%08.3f ", $timevrfytot) .
4692 "seconds verifying test results.\n";
4693 logmsg "Spent ". sprintf("%08.3f ", $timetesttot) .
4694 "seconds doing all of the above.\n";
4697 logmsg "\nTest server starting and verification time per test ".
4698 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4699 logmsg "-time- test\n";
4700 logmsg "------ ----\n";
4701 foreach my $txt (@timesrvr) {
4702 last if((not $fullstats) && (not $counter--));
4707 logmsg "\nTest definition reading and preparation time per test ".
4708 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4709 logmsg "-time- test\n";
4710 logmsg "------ ----\n";
4711 foreach my $txt (@timeprep) {
4712 last if((not $fullstats) && (not $counter--));
4717 logmsg "\nTest tool execution time per test ".
4718 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4719 logmsg "-time- test\n";
4720 logmsg "------ ----\n";
4721 foreach my $txt (@timetool) {
4722 last if((not $fullstats) && (not $counter--));
4727 logmsg "\nTest server logs lock removal time per test ".
4728 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4729 logmsg "-time- test\n";
4730 logmsg "------ ----\n";
4731 foreach my $txt (@timelock) {
4732 last if((not $fullstats) && (not $counter--));
4737 logmsg "\nTest results verification time per test ".
4738 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4739 logmsg "-time- test\n";
4740 logmsg "------ ----\n";
4741 foreach my $txt (@timevrfy) {
4742 last if((not $fullstats) && (not $counter--));
4747 logmsg "\nTotal time per test ".
4748 sprintf("(%s)...\n\n", (not $fullstats)?"top $counter":"full");
4749 logmsg "-time- test\n";
4750 logmsg "------ ----\n";
4751 foreach my $txt (@timetest) {
4752 last if((not $fullstats) && (not $counter--));
4759 #######################################################################
4760 # Check options to this test program
4767 if ($ARGV[0] eq "-v") {
4771 elsif($ARGV[0] =~ /^-b(.*)/) {
4773 if($portno =~ s/(\d+)$//) {
4777 elsif ($ARGV[0] eq "-c") {
4778 # use this path to curl instead of default
4779 $DBGCURL=$CURL="\"$ARGV[1]\"";
4782 elsif ($ARGV[0] eq "-vc") {
4783 # use this path to a curl used to verify servers
4785 # Particularly useful when you introduce a crashing bug somewhere in
4786 # the development version as then it won't be able to run any tests
4787 # since it can't verify the servers!
4789 $VCURL="\"$ARGV[1]\"";
4792 elsif ($ARGV[0] eq "-d") {
4793 # have the servers display protocol output
4796 elsif ($ARGV[0] eq "-g") {
4797 # run this test with gdb
4800 elsif ($ARGV[0] eq "-gw") {
4801 # run this test with windowed gdb
4805 elsif($ARGV[0] eq "-s") {
4809 elsif($ARGV[0] eq "-am") {
4810 # automake-style output
4814 elsif($ARGV[0] eq "-n") {
4818 elsif($ARGV[0] =~ /^-t(.*)/) {
4823 if($xtra =~ s/(\d+)$//) {
4826 # we undef valgrind to make this fly in comparison
4829 elsif($ARGV[0] eq "-a") {
4830 # continue anyway, even if a test fail
4833 elsif($ARGV[0] eq "-e") {
4834 # run the tests cases event based if possible
4837 elsif($ARGV[0] eq "-p") {
4840 elsif($ARGV[0] eq "-l") {
4841 # lists the test case names only
4844 elsif($ARGV[0] eq "-k") {
4845 # keep stdout and stderr files after tests
4848 elsif($ARGV[0] eq "-r") {
4849 # run time statistics needs Time::HiRes
4850 if($Time::HiRes::VERSION) {
4851 keys(%timeprepini) = 1000;
4852 keys(%timesrvrini) = 1000;
4853 keys(%timesrvrend) = 1000;
4854 keys(%timetoolini) = 1000;
4855 keys(%timetoolend) = 1000;
4856 keys(%timesrvrlog) = 1000;
4857 keys(%timevrfyend) = 1000;
4862 elsif($ARGV[0] eq "-rf") {
4863 # run time statistics needs Time::HiRes
4864 if($Time::HiRes::VERSION) {
4865 keys(%timeprepini) = 1000;
4866 keys(%timesrvrini) = 1000;
4867 keys(%timesrvrend) = 1000;
4868 keys(%timetoolini) = 1000;
4869 keys(%timetoolend) = 1000;
4870 keys(%timesrvrlog) = 1000;
4871 keys(%timevrfyend) = 1000;
4876 elsif(($ARGV[0] eq "-h") || ($ARGV[0] eq "--help")) {
4879 Usage: runtests.pl [options] [test selection(s)]
4880 -a continue even if a test fails
4881 -bN use base port number N for test servers (default $base)
4882 -c path use this curl executable
4883 -d display server debug info
4884 -g run the test case with gdb
4885 -gw run the test case with gdb as a windowed application
4887 -k keep stdout and stderr files present after tests
4888 -l list all test case names/descriptions
4890 -p print log file contents when a test fails
4891 -r run time statistics
4892 -rf full run time statistics
4894 -am automake style output PASS/FAIL: [number] [name]
4895 -t[N] torture (simulate memory alloc failures); N means fail Nth alloc
4897 -vc path use this curl only to verify the existing servers
4898 [num] like "5 6 9" or " 5 to 22 " to run those tests only
4899 [!num] like "!5 !6 !9" to disable those tests
4900 [keyword] like "IPv6" to select only tests containing the key word
4901 [!keyword] like "!cookies" to disable any tests containing the key word
4906 elsif($ARGV[0] =~ /^(\d+)/) {
4909 for($fromnum .. $number) {
4918 elsif($ARGV[0] =~ /^to$/i) {
4919 $fromnum = $number+1;
4921 elsif($ARGV[0] =~ /^!(\d+)/) {
4925 elsif($ARGV[0] =~ /^!(.+)/) {
4926 $disabled_keywords{$1}=$1;
4928 elsif($ARGV[0] =~ /^([-[{a-zA-Z].*)/) {
4929 $enabled_keywords{$1}=$1;
4932 print "Unknown option: $ARGV[0]\n";
4938 if(@testthis && ($testthis[0] ne "")) {
4939 $TESTCASES=join(" ", @testthis);
4943 # we have found valgrind on the host, use it
4945 # verify that we can invoke it fine
4946 my $code = runclient("valgrind >/dev/null 2>&1");
4948 if(($code>>8) != 1) {
4949 #logmsg "Valgrind failure, disable it\n";
4953 # since valgrind 2.1.x, '--tool' option is mandatory
4954 # use it, if it is supported by the version installed on the system
4955 runclient("valgrind --help 2>&1 | grep -- --tool > /dev/null 2>&1");
4957 $valgrind_tool="--tool=memcheck";
4962 # A shell script. This is typically when built with libtool,
4963 $valgrind="../libtool --mode=execute $valgrind";
4967 # valgrind 3 renamed the --logfile option to --log-file!!!
4968 my $ver=join(' ', runclientoutput("valgrind --version"));
4969 # cut off all but digits and dots
4970 $ver =~ s/[^0-9.]//g;
4972 if($ver =~ /^(\d+)/) {
4975 $valgrind_logfile="--log-file";
4982 # open the executable curl and read the first 4 bytes of it
4983 open(CHECK, "<$CURL");
4985 sysread CHECK, $c, 4;
4988 # A shell script. This is typically when built with libtool,
4990 $gdb = "../libtool --mode=execute gdb";
4994 $HTTPPORT = $base++; # HTTP server port
4995 $HTTPSPORT = $base++; # HTTPS (stunnel) server port
4996 $FTPPORT = $base++; # FTP server port
4997 $FTPSPORT = $base++; # FTPS (stunnel) server port
4998 $HTTP6PORT = $base++; # HTTP IPv6 server port
4999 $FTP2PORT = $base++; # FTP server 2 port
5000 $FTP6PORT = $base++; # FTP IPv6 port
5001 $TFTPPORT = $base++; # TFTP (UDP) port
5002 $TFTP6PORT = $base++; # TFTP IPv6 (UDP) port
5003 $SSHPORT = $base++; # SSH (SCP/SFTP) port
5004 $SOCKSPORT = $base++; # SOCKS port
5005 $POP3PORT = $base++; # POP3 server port
5006 $POP36PORT = $base++; # POP3 IPv6 server port
5007 $IMAPPORT = $base++; # IMAP server port
5008 $IMAP6PORT = $base++; # IMAP IPv6 server port
5009 $SMTPPORT = $base++; # SMTP server port
5010 $SMTP6PORT = $base++; # SMTP IPv6 server port
5011 $RTSPPORT = $base++; # RTSP server port
5012 $RTSP6PORT = $base++; # RTSP IPv6 server port
5013 $GOPHERPORT = $base++; # Gopher IPv4 server port
5014 $GOPHER6PORT = $base++; # Gopher IPv6 server port
5015 $HTTPTLSPORT = $base++; # HTTP TLS (non-stunnel) server port
5016 $HTTPTLS6PORT = $base++; # HTTP TLS (non-stunnel) IPv6 server port
5017 $HTTPPROXYPORT = $base++; # HTTP proxy port, when using CONNECT
5018 $HTTPPIPEPORT = $base++; # HTTP pipelining port
5019 $HTTPUNIXPATH = 'http.sock'; # HTTP server Unix domain socket path
5021 #######################################################################
5022 # clear and create logging directory:
5026 mkdir($LOGDIR, 0777);
5028 #######################################################################
5029 # initialize some variables
5033 init_serverpidfile_hash();
5035 #######################################################################
5036 # Output curl version and host info being tested
5043 #######################################################################
5044 # Fetch all disabled tests, if there are any
5050 if(open(D, "<$file")) {
5057 $disabled{$1}=$1; # disable this test number
5064 # globally disabled tests
5065 disabledtests("$TESTDIR/DISABLED");
5067 # locally disabled tests, ignored by git etc
5068 disabledtests("$TESTDIR/DISABLED.local");
5070 #######################################################################
5071 # If 'all' tests are requested, find out all test numbers
5074 if ( $TESTCASES eq "all") {
5075 # Get all commands and find out their test numbers
5076 opendir(DIR, $TESTDIR) || die "can't opendir $TESTDIR: $!";
5077 my @cmds = grep { /^test([0-9]+)$/ && -f "$TESTDIR/$_" } readdir(DIR);
5080 $TESTCASES=""; # start with no test cases
5082 # cut off everything but the digits
5084 $_ =~ s/[a-z\/\.]*//g;
5086 # sort the numbers from low to high
5087 foreach my $n (sort { $a <=> $b } @cmds) {
5089 # skip disabled test cases
5090 my $why = "configured as DISABLED";
5093 $teststat[$n]=$why; # store reason for this test case
5096 $TESTCASES .= " $n";
5102 if (-e "$TESTDIR/test$_") {
5105 } split(" ", $TESTCASES);
5106 if($verified eq "") {
5107 print "No existing test cases were specified\n";
5110 $TESTCASES = $verified;
5113 #######################################################################
5114 # Start the command line log
5116 open(CMDLOG, ">$CURLLOG") ||
5117 logmsg "can't log command lines to $CURLLOG\n";
5119 #######################################################################
5121 # Display the contents of the given file. Line endings are canonicalized
5122 # and excessively long files are elided
5123 sub displaylogcontent {
5125 if(open(SINGLE, "<$file")) {
5129 while(my $string = <SINGLE>) {
5130 $string =~ s/\r\n/\n/g;
5131 $string =~ s/[\r\f\032]/\n/g;
5132 $string .= "\n" unless ($string =~ /\n$/);
5134 for my $line (split("\n", $string)) {
5135 $line =~ s/\s*\!$//;
5137 push @tail, " $line\n";
5142 $truncate = $linecount > 1000;
5148 my $tailtotal = scalar @tail;
5149 if($tailtotal > $tailshow) {
5150 $tailskip = $tailtotal - $tailshow;
5151 logmsg "=== File too long: $tailskip lines omitted here\n";
5153 for($tailskip .. $tailtotal-1) {
5163 opendir(DIR, "$LOGDIR") ||
5164 die "can't open dir: $!";
5165 my @logs = readdir(DIR);
5168 logmsg "== Contents of files in the $LOGDIR/ dir after test $testnum\n";
5169 foreach my $log (sort @logs) {
5170 if($log =~ /\.(\.|)$/) {
5171 next; # skip "." and ".."
5173 if($log =~ /^\.nfs/) {
5176 if(($log eq "memdump") || ($log eq "core")) {
5177 next; # skip "memdump" and "core"
5179 if((-d "$LOGDIR/$log") || (! -s "$LOGDIR/$log")) {
5180 next; # skip directory and empty files
5182 if(($log =~ /^stdout\d+/) && ($log !~ /^stdout$testnum/)) {
5183 next; # skip stdoutNnn of other tests
5185 if(($log =~ /^stderr\d+/) && ($log !~ /^stderr$testnum/)) {
5186 next; # skip stderrNnn of other tests
5188 if(($log =~ /^upload\d+/) && ($log !~ /^upload$testnum/)) {
5189 next; # skip uploadNnn of other tests
5191 if(($log =~ /^curl\d+\.out/) && ($log !~ /^curl$testnum\.out/)) {
5192 next; # skip curlNnn.out of other tests
5194 if(($log =~ /^test\d+\.txt/) && ($log !~ /^test$testnum\.txt/)) {
5195 next; # skip testNnn.txt of other tests
5197 if(($log =~ /^file\d+\.txt/) && ($log !~ /^file$testnum\.txt/)) {
5198 next; # skip fileNnn.txt of other tests
5200 if(($log =~ /^netrc\d+/) && ($log !~ /^netrc$testnum/)) {
5201 next; # skip netrcNnn of other tests
5203 if(($log =~ /^trace\d+/) && ($log !~ /^trace$testnum/)) {
5204 next; # skip traceNnn of other tests
5206 if(($log =~ /^valgrind\d+/) && ($log !~ /^valgrind$testnum(\..*|)$/)) {
5207 next; # skip valgrindNnn of other tests
5209 logmsg "=== Start of file $log\n";
5210 displaylogcontent("$LOGDIR/$log");
5211 logmsg "=== End of file $log\n";
5215 #######################################################################
5216 # The main test-loop
5224 my @at = split(" ", $TESTCASES);
5229 foreach $testnum (@at) {
5231 $lasttest = $testnum if($testnum > $lasttest);
5234 my $error = singletest($run_event_based, $testnum, $count, scalar(@at));
5236 # not a test we can run
5240 $total++; # number of tests we've run
5243 $failed.= "$testnum ";
5245 # display all files in log/ in a nice way
5246 displaylogs($testnum);
5249 # a test failed, abort
5250 logmsg "\n - abort tests\n";
5255 $ok++; # successful test counter
5258 # loop for next test
5261 my $sofar = time() - $start;
5263 #######################################################################
5268 # Tests done, stop the servers
5269 stopservers($verbose);
5271 my $all = $total + $skipped;
5273 runtimestats($lasttest);
5276 logmsg sprintf("TESTDONE: $ok tests out of $total reported OK: %d%%\n",
5280 logmsg "TESTFAIL: These test cases failed: $failed\n";
5284 logmsg "TESTFAIL: No tests were performed\n";
5288 logmsg "TESTDONE: $all tests were considered during ".
5289 sprintf("%.0f", $sofar) ." seconds.\n";
5292 if($skipped && !$short) {
5294 logmsg "TESTINFO: $skipped tests were skipped due to these restraints:\n";
5296 for(keys %skipped) {
5298 printf "TESTINFO: \"%s\" %d times (", $r, $skipped{$_};
5300 # now show all test case numbers that had this reason for being
5304 for(0 .. scalar @teststat) {
5306 if($teststat[$_] && ($teststat[$_] eq $r)) {
5315 logmsg " and ".($c-$max)." more";
5321 if($total && ($ok != $total)) {