# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# These should be the only variables that might be needed to get edited:
BEGIN {
- @INC=(@INC, $ENV{'srcdir'}, ".");
+ push(@INC, $ENV{'srcdir'}) if(defined $ENV{'srcdir'});
+ push(@INC, ".");
# run time statistics needs Time::HiRes
eval {
no warnings "all";
my $GOPHER6PORT; # Gopher IPv6 server port
my $HTTPTLSPORT; # HTTP TLS (non-stunnel) server port
my $HTTPTLS6PORT; # HTTP TLS (non-stunnel) IPv6 server port
+my $HTTPPROXYPORT; # HTTP proxy port, when using CONNECT
+my $HTTPPIPEPORT; # HTTP pipelining port
+my $HTTPUNIXPATH; # HTTP server Unix domain socket path
my $srcdir = $ENV{'srcdir'} || '.';
my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
my $TESTDIR="$srcdir/data";
my $LIBDIR="./libtest";
my $UNITDIR="./unit";
+# TODO: change this to use server_inputfilename()
my $SERVERIN="$LOGDIR/server.input"; # what curl sent the server
my $SERVER2IN="$LOGDIR/server2.input"; # what curl sent the second server
+my $PROXYIN="$LOGDIR/proxy.input"; # what curl sent the proxy
my $CURLLOG="$LOGDIR/curl.log"; # all command lines run
my $FTPDCMD="$LOGDIR/ftpserver.cmd"; # copy ftp server instructions here
my $SERVERLOGS_LOCK="$LOGDIR/serverlogs.lock"; # server logs advisor read lock
my $perl="perl -I$srcdir";
my $server_response_maxtime=13;
-my $debug_build=0; # curl built with --enable-debug
-my $curl_debug=0; # curl built with --enable-curldebug (memory tracking)
+my $debug_build=0; # built debug enabled (--enable-debug)
+my $has_memory_tracking=0; # built with memory tracking (--enable-curldebug)
my $libtool;
# name of the file that the memory debugging creates:
my $pwd = getcwd(); # current working directory
my $start;
-my $forkserver=0;
my $ftpchecktime=1; # time it took to verify our test FTP server
-my $stunnel = checkcmd("stunnel4") || checkcmd("stunnel");
+my $stunnel = checkcmd("stunnel4") || checkcmd("tstunnel") || checkcmd("stunnel");
my $valgrind = checktestcmd("valgrind");
my $valgrind_logfile="--logfile";
my $valgrind_tool;
my $gdb = checktestcmd("gdb");
my $httptlssrv = find_httptlssrv();
-my $ssl_version; # set if libcurl is built with SSL support
-my $large_file; # set if libcurl is built with large file support
-my $has_idn; # set if libcurl is built with IDN support
-my $http_ipv6; # set if HTTP server has IPv6 support
-my $ftp_ipv6; # set if FTP server has IPv6 support
-my $tftp_ipv6; # set if TFTP server has IPv6 support
-my $gopher_ipv6; # set if Gopher server has IPv6 support
-my $has_ipv6; # set if libcurl is built with IPv6 support
-my $has_libz; # set if libcurl is built with libz support
+my $ssl_version; # set if libcurl is built with SSL support
+my $large_file; # set if libcurl is built with large file support
+my $has_idn; # set if libcurl is built with IDN support
+my $http_ipv6; # set if HTTP server has IPv6 support
+my $http_unix; # set if HTTP server has Unix sockets support
+my $ftp_ipv6; # set if FTP server has IPv6 support
+my $tftp_ipv6; # set if TFTP server has IPv6 support
+my $gopher_ipv6; # set if Gopher server has IPv6 support
+my $has_ipv6; # set if libcurl is built with IPv6 support
+my $has_unix; # set if libcurl is built with Unix sockets support
+my $has_libz; # set if libcurl is built with libz support
my $has_getrlimit; # set if system has getrlimit()
-my $has_ntlm; # set if libcurl is built with NTLM support
-my $has_ntlm_wb; # set if libcurl is built with NTLM delegation to winbind
-my $has_charconv;# set if libcurl is built with CharConv support
-my $has_tls_srp; # set if libcurl is built with TLS-SRP support
-
-my $has_openssl; # built with a lib using an OpenSSL-like API
-my $has_gnutls; # built with GnuTLS
-my $has_nss; # built with NSS
-my $has_yassl; # built with yassl
-my $has_polarssl;# built with polarssl
-my $has_axtls; # built with axTLS
+my $has_ntlm; # set if libcurl is built with NTLM support
+my $has_ntlm_wb; # set if libcurl is built with NTLM delegation to winbind
+my $has_sspi; # set if libcurl is built with Windows SSPI
+my $has_gssapi; # set if libcurl is built with a GSS-API library
+my $has_kerberos; # set if libcurl is built with Kerberos support
+my $has_spnego; # set if libcurl is built with SPNEGO support
+my $has_charconv; # set if libcurl is built with CharConv support
+my $has_tls_srp; # set if libcurl is built with TLS-SRP support
+my $has_metalink; # set if curl is built with Metalink support
+my $has_http2; # set if libcurl is built with HTTP2 support
+my $has_crypto; # set if libcurl is built with cryptographic support
+my $has_cares; # set if built with c-ares
+my $has_threadedres;# set if built with threaded resolver
+
+# this version is decided by the particular nghttp2 library that is being used
+my $h2cver = "h2c-14";
+
+my $has_openssl; # built with a lib using an OpenSSL-like API
+my $has_gnutls; # built with GnuTLS
+my $has_nss; # built with NSS
+my $has_yassl; # built with yassl
+my $has_polarssl; # built with polarssl
+my $has_axtls; # built with axTLS
+my $has_winssl; # built with WinSSL (Secure Channel aka Schannel)
+my $has_darwinssl; # build with DarwinSSL (Secure Transport)
+
+my $has_sslpinning; # built with a TLS backend that supports pinning
my $has_shared = "unknown"; # built shared
-my $ssllib; # name of the lib we use (for human presentation)
-my $has_crypto; # set if libcurl is built with cryptographic support
-my $has_textaware; # set if running on a system that has a text mode concept
- # on files. Windows for example
+my $resolver; # name of the resolver backend (for human presentation)
+my $ssllib; # name of the SSL library we use (for human presentation)
+
+my $has_textaware; # set if running on a system that has a text mode concept
+ # on files. Windows for example
my @protocols; # array of lowercase supported protocol servers
my @teststat; # teststat[testnum]=reason, reasons for skip
my %disabled_keywords; # key words of tests to skip
my %enabled_keywords; # key words of tests to run
-my %disabled; # disabled test cases
+my %disabled; # disabled test cases
my $sshdid; # for socks server, ssh daemon version id
my $sshdvernum; # for socks server, ssh daemon version number
#
my $short;
+my $automakestyle;
my $verbose;
my $debugprotocol;
my $anyway;
my $keepoutfiles; # keep stdout and stderr files after tests
my $listonly; # only list the tests
my $postmortem; # display detailed info about failed tests
+my $run_event_based; # run curl with --test-event to test the event API
my %run; # running server
my %doesntrun; # servers that don't work, identified by pidfile
if (!$USER) {
$USER = $ENV{USERNAME}; # Windows
if (!$USER) {
- $USER = $ENV{LOGNAME}; # Some UNIX (I think)
+ $USER = $ENV{LOGNAME}; # Some Unix (I think)
}
}
# enable memory debugging if curl is compiled with it
$ENV{'CURL_MEMDEBUG'} = $memdump;
+$ENV{'CURL_ENTROPY'}="12345678";
+$ENV{'CURL_FORCETIME'}=1; # for debug NTLM magic
$ENV{'HOME'}=$pwd;
sub catch_zap {
for my $proto (('ftp', 'http', 'imap', 'pop3', 'smtp')) {
for my $ssl (('', 's')) {
for my $ipvnum ((4, 6)) {
- for my $idnum ((1, 2)) {
+ for my $idnum ((1, 2, 3)) {
my $serv = servername_id("$proto$ssl", $ipvnum, $idnum);
my $pidf = server_pidfilename("$proto$ssl", $ipvnum, $idnum);
$serverpidfile{$serv} = $pidf;
}
}
}
+ for my $proto (('http', 'imap', 'pop3', 'smtp')) {
+ for my $ssl (('', 's')) {
+ my $serv = servername_id("$proto$ssl", "unix", 1);
+ my $pidf = server_pidfilename("$proto$ssl", "unix", 1);
+ $serverpidfile{$serv} = $pidf;
+ }
+ }
}
#######################################################################
if(-f $pidfile && -s $pidfile && open(PID, "<$pidfile")) {
$pid2 = 0 + <PID>;
close(PID);
- if(($pid2 > 0) && kill(0, $pid2)) {
+ if(($pid2 > 0) && pidexists($pid2)) {
# if $pid2 is valid, then make sure this pid is alive, as
# otherwise it is just likely to be the _previous_ pidfile or
# similar!
#
sub runclient {
my ($cmd)=@_;
- return system($cmd);
+ my $ret = system($cmd);
+ print "CMD ($ret): $cmd\n" if($verbose && !$torture);
+ return $ret;
# This is one way to test curl on a remote machine
# my $out = system("ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'");
else {
$ret = runclient($testcmd);
}
- #logmsg "$_ Returned " . $ret >> 8 . "\n";
+ #logmsg "$_ Returned " . ($ret >> 8) . "\n";
# Now clear the variable again
delete $ENV{'CURL_MEMLIMIT'} if($ENV{'CURL_MEMLIMIT'});
# verify that it returns a proper error code, doesn't leak memory
# and doesn't core dump
- if($ret & 255) {
+ if(($ret & 255) || ($ret >> 8) >= 128) {
logmsg " system() returned $ret\n";
$fail=1;
}
# All servers relative to the given one must be stopped also
#
my @killservers;
- if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
+ if($server =~ /^(ftp|http|imap|pop3|smtp|httppipe)s((\d*)(-ipv6|-unix|))$/) {
# given a stunnel based ssl server, also kill non-ssl underlying one
push @killservers, "${1}${2}";
}
- elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|))$/) {
+ elsif($server =~ /^(ftp|http|imap|pop3|smtp|httppipe)((\d*)(-ipv6|-unix|))$/) {
# given a non-ssl server, also kill stunnel based ssl piggybacking one
push @killservers, "${1}s${2}";
}
# assign requested address")
#
sub verifyhttp {
- my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
+ my ($proto, $ipvnum, $idnum, $ip, $port_or_path) = @_;
my $server = servername_id($proto, $ipvnum, $idnum);
my $pid = 0;
my $bonus="";
+ # $port_or_path contains a path for Unix sockets, sws ignores the port
+ my $port = ($ipvnum eq "unix") ? 80 : $port_or_path;
my $verifyout = "$LOGDIR/".
servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
$flags .= "--silent ";
$flags .= "--verbose ";
$flags .= "--globoff ";
+ $flags .= "--unix-socket '$port_or_path' " if $ipvnum eq "unix";
$flags .= "-1 " if($has_axtls);
$flags .= "--insecure " if($proto eq 'https');
$flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\"";
if($proto eq "ftps") {
$extra .= "--insecure --ftp-ssl-control ";
}
- elsif($proto eq "smtp") {
- # SMTP is a bit different since it requires more options and it
- # has _no_ output!
- $extra .= "--mail-rcpt verifiedserver ";
- $extra .= "--mail-from fake ";
- $extra .= "--upload /dev/null ";
- $extra .= "--stderr - "; # move stderr to parse the verbose stuff
- }
my $flags = "--max-time $server_response_maxtime ";
$flags .= "--silent ";
if($pid > 0) {
# if we have a pid it is actually our ssh server,
# since runsshserver() unlinks previous pidfile
- if(!kill(0, $pid)) {
+ if(!pidexists($pid)) {
logmsg "RUN: SSH server has died after starting up\n";
checkdied($pid);
unlink($pidfile);
}
# Connect to sftp server, authenticate and run a remote pwd
# command using our generated configuration and key files
- my $cmd = "$sftp -b $sftpcmds -F $sftpconfig -S $ssh $ip > $sftplog 2>&1";
+ my $cmd = "\"$sftp\" -b $sftpcmds -F $sftpconfig -S \"$ssh\" $ip > $sftplog 2>&1";
my $res = runclient($cmd);
# Search for pwd command response in log file
if(open(SFTPLOGFILE, "<$sftplog")) {
close(FILE);
}
- if($data && ($data =~ /GNUTLS/) && open(FILE, "<$pidfile")) {
+ if($data && ($data =~ /(GNUTLS|GnuTLS)/) && open(FILE, "<$pidfile")) {
$pid=0+<FILE>;
close(FILE);
if($pid > 0) {
# if we have a pid it is actually our httptls server,
# since runhttptlsserver() unlinks previous pidfile
- if(!kill(0, $pid)) {
+ if(!pidexists($pid)) {
logmsg "RUN: $server server has died after starting up\n";
checkdied($pid);
unlink($pidfile);
if($pid > 0) {
# if we have a pid it is actually our socks server,
# since runsocksserver() unlinks previous pidfile
- if(!kill(0, $pid)) {
+ if(!pidexists($pid)) {
logmsg "RUN: SOCKS server has died after starting up\n";
checkdied($pid);
unlink($pidfile);
'pop3' => \&verifyftp,
'imap' => \&verifyftp,
'smtp' => \&verifyftp,
+ 'httppipe' => \&verifyhttp,
'ftps' => \&verifyftp,
'tftp' => \&verifyftp,
'ssh' => \&verifyssh,
# start the http server
#
sub runhttpserver {
- my ($proto, $verbose, $ipv6, $port) = @_;
+ my ($proto, $verbose, $alt, $port_or_path) = @_;
my $ip = $HOSTIP;
my $ipvnum = 4;
my $idnum = 1;
my $pidfile;
my $logfile;
my $flags = "";
+ my $exe = "$perl $srcdir/httpserver.pl";
+ my $verbose_flag = "--verbose ";
- if($ipv6) {
+ if($alt eq "ipv6") {
# if IPv6, use a different setup
$ipvnum = 6;
$ip = $HOST6IP;
}
+ elsif($alt eq "proxy") {
+ # basically the same, but another ID
+ $idnum = 2;
+ }
+ elsif($alt eq "pipe") {
+ # basically the same, but another ID
+ $idnum = 3;
+ $exe = "python $srcdir/http_pipe.py";
+ $verbose_flag .= "1 ";
+ }
+ elsif($alt eq "unix") {
+ # IP (protocol) is mutually exclusive with Unix sockets
+ $ipvnum = "unix";
+ }
$server = servername_id($proto, $ipvnum, $idnum);
$logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
- $flags .= "--fork " if($forkserver);
$flags .= "--gopher " if($proto eq "gopher");
- $flags .= "--verbose " if($debugprotocol);
+ $flags .= "--connect $HOSTIP " if($alt eq "proxy");
+ $flags .= $verbose_flag if($debugprotocol);
$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
$flags .= "--id $idnum " if($idnum > 1);
- $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
+ if($ipvnum eq "unix") {
+ $flags .= "--unix-socket '$port_or_path' ";
+ } else {
+ $flags .= "--ipv$ipvnum --port $port_or_path ";
+ }
+ $flags .= "--srcdir \"$srcdir\"";
+
+ my $cmd = "$exe $flags";
+ my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
+
+ if($httppid <= 0 || !pidexists($httppid)) {
+ # it is NOT alive
+ logmsg "RUN: failed to start the $srvrname server\n";
+ stopserver($server, "$pid2");
+ displaylogs($testnumcheck);
+ $doesntrun{$pidfile} = 1;
+ return (0,0);
+ }
+
+ # Server is up. Verify that we can speak to it.
+ my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
+ if(!$pid3) {
+ logmsg "RUN: $srvrname server failed verification\n";
+ # failed to talk to it properly. Kill the server and return failure
+ stopserver($server, "$httppid $pid2");
+ displaylogs($testnumcheck);
+ $doesntrun{$pidfile} = 1;
+ return (0,0);
+ }
+ $pid2 = $pid3;
+
+ if($verbose) {
+ logmsg "RUN: $srvrname server is now running PID $httppid\n";
+ }
+
+ sleep(1);
+
+ return ($httppid, $pid2);
+}
+
+#######################################################################
+# start the http server
+#
+sub runhttp_pipeserver {
+ my ($proto, $verbose, $alt, $port) = @_;
+ my $ip = $HOSTIP;
+ my $ipvnum = 4;
+ my $idnum = 1;
+ my $server;
+ my $srvrname;
+ my $pidfile;
+ my $logfile;
+ my $flags = "";
+
+ if($alt eq "ipv6") {
+ # No IPv6
+ }
+
+ $server = servername_id($proto, $ipvnum, $idnum);
+
+ $pidfile = $serverpidfile{$server};
- my $cmd = "$perl $srcdir/httpserver.pl $flags";
+ # don't retry if the server doesn't work
+ if ($doesntrun{$pidfile}) {
+ return (0,0);
+ }
+
+ my $pid = processexists($pidfile);
+ if($pid > 0) {
+ stopserver($server, "$pid");
+ }
+ unlink($pidfile) if(-f $pidfile);
+
+ $srvrname = servername_str($proto, $ipvnum, $idnum);
+
+ $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
+
+ $flags .= "--verbose 1 " if($debugprotocol);
+ $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
+ $flags .= "--id $idnum " if($idnum > 1);
+ $flags .= "--port $port --srcdir \"$srcdir\"";
+
+ my $cmd = "$srcdir/http_pipe.py $flags";
my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
- if($httppid <= 0 || !kill(0, $httppid)) {
+ if($httppid <= 0 || !pidexists($httppid)) {
# it is NOT alive
logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
my $cmd = "$perl $srcdir/secureserver.pl $flags";
my ($httpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
- if($httpspid <= 0 || !kill(0, $httpspid)) {
+ if($httpspid <= 0 || !pidexists($httpspid)) {
# it is NOT alive
logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
$flags .= "--http ";
$flags .= "--debug 1 " if($debugprotocol);
$flags .= "--port $port ";
- $flags .= "--srppasswd certs/srp-verifier-db ";
- $flags .= "--srppasswdconf certs/srp-verifier-conf";
+ $flags .= "--priority NORMAL:+SRP ";
+ $flags .= "--srppasswd $srcdir/certs/srp-verifier-db ";
+ $flags .= "--srppasswdconf $srcdir/certs/srp-verifier-conf";
my $cmd = "$httptlssrv $flags > $logfile 2>&1";
my ($httptlspid, $pid2) = startnew($cmd, $pidfile, 10, 1); # fake pidfile
- if($httptlspid <= 0 || !kill(0, $httptlspid)) {
+ if($httptlspid <= 0 || !pidexists($httptlspid)) {
# it is NOT alive
logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
my $cmd = "$perl $srcdir/ftpserver.pl $flags";
my ($ftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
- if($ftppid <= 0 || !kill(0, $ftppid)) {
+ if($ftppid <= 0 || !pidexists($ftppid)) {
# it is NOT alive
logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
my $cmd = "$perl $srcdir/secureserver.pl $flags";
my ($ftpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
- if($ftpspid <= 0 || !kill(0, $ftpspid)) {
+ if($ftpspid <= 0 || !pidexists($ftpspid)) {
# it is NOT alive
logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
my $cmd = "$perl $srcdir/tftpserver.pl $flags";
my ($tftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
- if($tftppid <= 0 || !kill(0, $tftppid)) {
+ if($tftppid <= 0 || !pidexists($tftppid)) {
# it is NOT alive
logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
my $cmd = "$perl $srcdir/rtspserver.pl $flags";
my ($rtsppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
- if($rtsppid <= 0 || !kill(0, $rtsppid)) {
+ if($rtsppid <= 0 || !pidexists($rtsppid)) {
# it is NOT alive
logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
# passed to startnew, when this happens startnew completes without being
# able to read the pidfile and consequently returns a zero pid2 above.
- if($sshpid <= 0 || !kill(0, $sshpid)) {
+ if($sshpid <= 0 || !pidexists($sshpid)) {
# it is NOT alive
logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
$sshlog = server_logfilename($LOGDIR, 'socks', $ipvnum, $idnum);
# start our socks server
- my $cmd="$ssh -N -F $sshconfig $ip > $sshlog 2>&1";
+ my $cmd="\"$ssh\" -N -F $sshconfig $ip > $sshlog 2>&1";
my ($sshpid, $pid2) = startnew($cmd, $pidfile, 30, 1); # fake pidfile
- if($sshpid <= 0 || !kill(0, $sshpid)) {
+ if($sshpid <= 0 || !pidexists($sshpid)) {
# it is NOT alive
logmsg "RUN: failed to start the $srvrname server\n";
display_sshlog();
# be used to verify that a server present in %run hash is still functional
#
sub responsive_http_server {
- my ($proto, $verbose, $ipv6, $port) = @_;
+ my ($proto, $verbose, $alt, $port_or_path) = @_;
my $ip = $HOSTIP;
my $ipvnum = 4;
my $idnum = 1;
- if($ipv6) {
+ if($alt eq "ipv6") {
# if IPv6, use a different setup
$ipvnum = 6;
$ip = $HOST6IP;
}
+ elsif($alt eq "proxy") {
+ $idnum = 2;
+ }
+ elsif($alt eq "unix") {
+ # IP (protocol) is mutually exclusive with Unix sockets
+ $ipvnum = "unix";
+ }
- return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
+ return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
}
#######################################################################
}
#######################################################################
-# filter out the specified pattern from the given input file and store the
-# results in the given output file
-#
-sub filteroff {
- my $infile=$_[0];
- my $filter=$_[1];
- my $ofile=$_[2];
-
- open(IN, "<$infile")
- || return 1;
-
- open(OUT, ">$ofile")
- || return 1;
-
- # logmsg "FILTER: off $filter from $infile to $ofile\n";
-
- while(<IN>) {
- $_ =~ s/$filter//;
- print OUT $_;
- }
- close(IN);
- close(OUT);
- return 0;
-}
-
-#######################################################################
# compare test results with the expected output, we might filter off
# some pattern that is allowed to differ, output test results
#
sub compare {
- # filter off patterns _before_ this comparison!
- my ($subject, $firstref, $secondref)=@_;
+ my ($testnum, $testname, $subject, $firstref, $secondref)=@_;
my $result = compareparts($firstref, $secondref);
if($result) {
+ # timestamp test result verification end
+ $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
+
if(!$short) {
- logmsg "\n $subject FAILED:\n";
+ logmsg "\n $testnum: $subject FAILED:\n";
logmsg showdiff($LOGDIR, $firstref, $secondref);
}
- else {
+ elsif(!$automakestyle) {
logmsg "FAILED\n";
}
+ else {
+ # automakestyle
+ logmsg "FAIL: $testnum - $testname - $subject\n";
+ }
}
return $result;
}
@version = <VERSOUT>;
close(VERSOUT);
+ $resolver="stock";
for(@version) {
chomp;
$libcurl = $2;
if($curl =~ /mingw32/) {
# This is a windows minw32 build, we need to translate the
- # given path to the "actual" windows path.
-
- my @m = `mount`;
- my $matchlen;
- my $bestmatch;
- my $mount;
-
-# example mount output:
-# C:\DOCUME~1\Temp on /tmp type user (binmode,noumount)
-# c:\ActiveState\perl on /perl type user (binmode)
-# C:\msys\1.0\bin on /usr/bin type user (binmode,cygexec,noumount)
-# C:\msys\1.0\bin on /bin type user (binmode,cygexec,noumount)
-
- foreach $mount (@m) {
- if( $mount =~ /(.*) on ([^ ]*) type /) {
- my ($mingw, $real)=($2, $1);
- if($pwd =~ /^$mingw/) {
- # the path we got from pwd starts with the path
- # we found on this line in the mount output
-
- my $len = length($real);
- if($len > $matchlen) {
- # we remember the match that is the longest
- $matchlen = $len;
- $bestmatch = $real;
- }
- }
- }
- }
- if(!$matchlen) {
- logmsg "Serious error, can't find our \"real\" path\n";
- }
- else {
- # now prepend the prefix from the mount command to build
- # our "actual path"
- $pwd = "$bestmatch$pwd";
- }
- $pwd =~ s#\\#/#g;
+ # given path to the "actual" windows path. The MSYS shell
+ # has a builtin 'pwd -W' command which converts the path.
+ $pwd = `sh -c "echo \$(pwd -W)"`;
+ chomp($pwd);
}
elsif ($curl =~ /win32/) {
# Native Windows builds don't understand the
# through a shell.
chomp($pwd = `cygpath -m $pwd`);
}
+ if ($libcurl =~ /winssl/i) {
+ $has_winssl=1;
+ $ssllib="WinSSL";
+ }
elsif ($libcurl =~ /openssl/i) {
$has_openssl=1;
+ $has_sslpinning=1;
$ssllib="OpenSSL";
}
elsif ($libcurl =~ /gnutls/i) {
$has_gnutls=1;
+ $has_sslpinning=1;
$ssllib="GnuTLS";
}
elsif ($libcurl =~ /nss/i) {
}
elsif ($libcurl =~ /yassl/i) {
$has_yassl=1;
- $has_openssl=1;
$ssllib="yassl";
}
elsif ($libcurl =~ /polarssl/i) {
$has_polarssl=1;
- $has_openssl=1;
$ssllib="polarssl";
- }
+ }
elsif ($libcurl =~ /axtls/i) {
$has_axtls=1;
$ssllib="axTLS";
}
+ elsif ($libcurl =~ /securetransport/i) {
+ $has_darwinssl=1;
+ $ssllib="DarwinSSL";
+ }
+ if ($libcurl =~ /ares/i) {
+ $has_cares=1;
+ $resolver="c-ares";
+ }
}
elsif($_ =~ /^Protocols: (.*)/i) {
# these are the protocols compiled in to this libcurl
@protocols = split(' ', lc($1));
# Generate a "proto-ipv6" version of each protocol to match the
- # IPv6 <server> name. This works even if IPv6 support isn't
+ # IPv6 <server> name and a "proto-unix" to match the variant which
+ # uses Unix domain sockets. This works even if support isn't
# compiled in because the <features> test will fail.
- push @protocols, map($_ . '-ipv6', @protocols);
+ push @protocols, map(("$_-ipv6", "$_-unix"), @protocols);
+
+ # 'http-proxy' is used in test cases to do CONNECT through
+ push @protocols, 'http-proxy';
+
+ # 'http-pipe' is the special server for testing pipelining
+ push @protocols, 'http-pipe';
# 'none' is used in test cases to mean no server
push @protocols, 'none';
elsif($_ =~ /^Features: (.*)/i) {
$feat = $1;
if($feat =~ /TrackMemory/i) {
- # curl was built with --enable-curldebug (memory tracking)
- $curl_debug = 1;
+ # built with memory tracking support (--enable-curldebug)
+ $has_memory_tracking = 1;
}
if($feat =~ /debug/i) {
# curl was built with --enable-debug
if($feat =~ /IPv6/i) {
$has_ipv6 = 1;
}
+ if($feat =~ /UnixSockets/i) {
+ $has_unix = 1;
+ }
if($feat =~ /libz/i) {
$has_libz = 1;
}
if($feat =~ /NTLM/i) {
# NTLM enabled
$has_ntlm=1;
+
+ # Use this as a proxy for any cryptographic authentication
+ $has_crypto=1;
}
if($feat =~ /NTLM_WB/i) {
# NTLM delegation to winbind daemon ntlm_auth helper enabled
$has_ntlm_wb=1;
}
+ if($feat =~ /SSPI/i) {
+ # SSPI enabled
+ $has_sspi=1;
+ }
+ if($feat =~ /GSS-API/i) {
+ # GSS-API enabled
+ $has_gssapi=1;
+ }
+ if($feat =~ /Kerberos/i) {
+ # Kerberos enabled
+ $has_kerberos=1;
+
+ # Use this as a proxy for any cryptographic authentication
+ $has_crypto=1;
+ }
+ if($feat =~ /SPNEGO/i) {
+ # SPNEGO enabled
+ $has_spnego=1;
+
+ # Use this as a proxy for any cryptographic authentication
+ $has_crypto=1;
+ }
if($feat =~ /CharConv/i) {
# CharConv enabled
$has_charconv=1;
# TLS-SRP enabled
$has_tls_srp=1;
}
+ if($feat =~ /Metalink/i) {
+ # Metalink enabled
+ $has_metalink=1;
+ }
+ if($feat =~ /AsynchDNS/i) {
+ if(!$has_cares) {
+ # this means threaded resolver
+ $has_threadedres=1;
+ $resolver="threaded";
+ }
+ }
+ if($feat =~ /HTTP2/) {
+ # http2 enabled
+ $has_http2=1;
+ }
}
#
# Test harness currently uses a non-stunnel server in order to
}
if($has_ipv6) {
- # client has ipv6 support
+ # client has IPv6 support
# check if the HTTP server has it!
my @sws = `server/sws --version`;
if($sws[0] =~ /IPv6/) {
- # HTTP server has ipv6 support!
+ # HTTP server has IPv6 support!
$http_ipv6 = 1;
$gopher_ipv6 = 1;
}
# check if the FTP server has it!
@sws = `server/sockfilt --version`;
if($sws[0] =~ /IPv6/) {
- # FTP server has ipv6 support!
+ # FTP server has IPv6 support!
$ftp_ipv6 = 1;
}
}
- if(!$curl_debug && $torture) {
- die "can't run torture tests since curl was not built with curldebug";
+ if($has_unix) {
+ # client has Unix sockets support, check whether the HTTP server has it
+ my @sws = `server/sws --version`;
+ $http_unix = 1 if($sws[0] =~ /unix/);
+ }
+
+ if(!$has_memory_tracking && $torture) {
+ die "can't run torture tests since curl was built without ".
+ "TrackMemory feature (--enable-curldebug)";
}
$has_shared = `sh $CURLCONFIG --built-shared`;
chomp $has_shared;
- # curl doesn't list cryptographic support separately, so assume it's
- # always available
- $has_crypto=1;
-
my $hostname=join(' ', runclientoutput("hostname"));
my $hosttype=join(' ', runclientoutput("uname -a"));
"* Host: $hostname",
"* System: $hosttype");
+ if($has_memory_tracking && $has_threadedres) {
+ $has_memory_tracking = 0;
+ logmsg("*\n",
+ "*** DISABLES memory tracking when using threaded resolver\n",
+ "*\n");
+ }
+
logmsg sprintf("* Server SSL: %8s", $stunnel?"ON ":"OFF");
logmsg sprintf(" libcurl SSL: %s\n", $ssl_version?"ON ":"OFF");
logmsg sprintf("* debug build: %8s", $debug_build?"ON ":"OFF");
- logmsg sprintf(" track memory: %s\n", $curl_debug?"ON ":"OFF");
+ logmsg sprintf(" track memory: %s\n", $has_memory_tracking?"ON ":"OFF");
logmsg sprintf("* valgrind: %8s", $valgrind?"ON ":"OFF");
logmsg sprintf(" HTTP IPv6 %s\n", $http_ipv6?"ON ":"OFF");
+ logmsg sprintf("* HTTP Unix %s\n", $http_unix?"ON ":"OFF");
logmsg sprintf("* FTP IPv6 %8s", $ftp_ipv6?"ON ":"OFF");
logmsg sprintf(" Libtool lib: %s\n", $libtool?"ON ":"OFF");
- logmsg sprintf("* Shared build: %s\n", $has_shared);
+ logmsg sprintf("* Shared build: %-3s", $has_shared);
+ logmsg sprintf(" Resolver: %s\n", $resolver);
if($ssl_version) {
logmsg sprintf("* SSL library: %13s\n", $ssllib);
}
}
logmsg "\n";
}
+ logmsg sprintf("* HTTP-PIPE/%d \n", $HTTPPIPEPORT);
+
+ if($has_unix) {
+ logmsg "* Unix socket paths:\n";
+ if($http_unix) {
+ logmsg sprintf("* HTTP-Unix:%s\n", $HTTPUNIXPATH);
+ }
+ }
$has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys');
$$thing =~ s/%HTTP6PORT/$HTTP6PORT/g;
$$thing =~ s/%HTTPSPORT/$HTTPSPORT/g;
$$thing =~ s/%HTTPPORT/$HTTPPORT/g;
+ $$thing =~ s/%HTTPPIPEPORT/$HTTPPIPEPORT/g;
+ $$thing =~ s/%PROXYPORT/$HTTPPROXYPORT/g;
$$thing =~ s/%IMAP6PORT/$IMAP6PORT/g;
$$thing =~ s/%IMAPPORT/$IMAPPORT/g;
$$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
$$thing =~ s/%TFTPPORT/$TFTPPORT/g;
+ # server Unix domain socket paths
+
+ $$thing =~ s/%HTTPUNIXPATH/$HTTPUNIXPATH/g;
+
# client IP addresses
$$thing =~ s/%CLIENT6IP/$CLIENT6IP/g;
$$thing =~ s/%FTPTIME2/$ftp2/g;
$$thing =~ s/%FTPTIME3/$ftp3/g;
+
+ # HTTP2
+
+ $$thing =~ s/%H2CVER/$h2cver/g;
}
sub fixarray {
# Run a single specified test case
#
sub singletest {
- my ($testnum, $count, $total)=@_;
+ my ($evbased, # 1 means switch on if possible (and "curl" is tested)
+ # returns "not a test" if it can't be used for this test
+ $testnum,
+ $count,
+ $total)=@_;
my @what;
my $why;
$timeprepini{$testnum} = Time::HiRes::time() if($timestats);
if($disttests !~ /test$testnum\W/ ) {
- logmsg "Warning: test$testnum not present in tests/data/Makefile.am\n";
+ logmsg "Warning: test$testnum not present in tests/data/Makefile.inc\n";
}
if($disabled{$testnum}) {
logmsg "Warning: test$testnum is explicitly disabled\n";
@what = getpart("client", "features");
}
+ # We require a feature to be present
for(@what) {
my $f = $_;
$f =~ s/\s//g;
- $feature{$f}=$f; # we require this feature
+ if($f =~ /^([^!].*)$/) {
+ # Store the feature for later
+ $feature{$1} = $1;
- if($f eq "SSL") {
- if($ssl_version) {
- next;
+ if($1 eq "SSL") {
+ if($ssl_version) {
+ next;
+ }
}
- }
- elsif($f eq "OpenSSL") {
- if($has_openssl) {
- next;
+ elsif($1 eq "SSLpinning") {
+ if($has_sslpinning) {
+ next;
+ }
}
- }
- elsif($f eq "GnuTLS") {
- if($has_gnutls) {
- next;
+ elsif($1 eq "OpenSSL") {
+ if($has_openssl) {
+ next;
+ }
}
- }
- elsif($f eq "NSS") {
- if($has_nss) {
- next;
+ elsif($1 eq "GnuTLS") {
+ if($has_gnutls) {
+ next;
+ }
}
- }
- elsif($f eq "axTLS") {
- if($has_axtls) {
- next;
+ elsif($1 eq "NSS") {
+ if($has_nss) {
+ next;
+ }
}
- }
- elsif($f eq "unittest") {
- if($debug_build) {
- next;
+ elsif($1 eq "axTLS") {
+ if($has_axtls) {
+ next;
+ }
}
- }
- elsif($f eq "debug") {
- if($debug_build) {
- next;
+ elsif($1 eq "WinSSL") {
+ if($has_winssl) {
+ next;
+ }
}
- }
- elsif($f eq "large_file") {
- if($large_file) {
- next;
+ elsif($1 eq "DarwinSSL") {
+ if($has_darwinssl) {
+ next;
+ }
}
- }
- elsif($f eq "idn") {
- if($has_idn) {
- next;
+ elsif($1 eq "unittest") {
+ if($debug_build) {
+ next;
+ }
}
- }
- elsif($f eq "ipv6") {
- if($has_ipv6) {
- next;
+ elsif($1 eq "debug") {
+ if($debug_build) {
+ next;
+ }
}
- }
- elsif($f eq "libz") {
- if($has_libz) {
- next;
+ elsif($1 eq "TrackMemory") {
+ if($has_memory_tracking) {
+ next;
+ }
}
- }
- elsif($f eq "NTLM") {
- if($has_ntlm) {
- next;
+ elsif($1 eq "large_file") {
+ if($large_file) {
+ next;
+ }
}
- }
- elsif($f eq "NTLM_WB") {
- if($has_ntlm_wb) {
- next;
+ elsif($1 eq "idn") {
+ if($has_idn) {
+ next;
+ }
}
- }
- elsif($f eq "getrlimit") {
- if($has_getrlimit) {
+ elsif($1 eq "ipv6") {
+ if($has_ipv6) {
+ next;
+ }
+ }
+ elsif($1 eq "libz") {
+ if($has_libz) {
+ next;
+ }
+ }
+ elsif($1 eq "NTLM") {
+ if($has_ntlm) {
+ next;
+ }
+ }
+ elsif($1 eq "NTLM_WB") {
+ if($has_ntlm_wb) {
+ next;
+ }
+ }
+ elsif($1 eq "SSPI") {
+ if($has_sspi) {
+ next;
+ }
+ }
+ elsif($1 eq "GSS-API") {
+ if($has_gssapi) {
+ next;
+ }
+ }
+ elsif($1 eq "Kerberos") {
+ if($has_kerberos) {
+ next;
+ }
+ }
+ elsif($1 eq "SPNEGO") {
+ if($has_spnego) {
+ next;
+ }
+ }
+ elsif($1 eq "getrlimit") {
+ if($has_getrlimit) {
+ next;
+ }
+ }
+ elsif($1 eq "crypto") {
+ if($has_crypto) {
+ next;
+ }
+ }
+ elsif($1 eq "TLS-SRP") {
+ if($has_tls_srp) {
+ next;
+ }
+ }
+ elsif($1 eq "Metalink") {
+ if($has_metalink) {
+ next;
+ }
+ }
+ elsif($1 eq "http2") {
+ if($has_http2) {
+ next;
+ }
+ }
+ elsif($1 eq "socks") {
next;
}
- }
- elsif($f eq "crypto") {
- if($has_crypto) {
+ elsif($1 eq "unix-sockets") {
+ next if $has_unix;
+ }
+ # See if this "feature" is in the list of supported protocols
+ elsif (grep /^\Q$1\E$/i, @protocols) {
next;
}
+
+ $why = "curl lacks $1 support";
+ last;
}
- elsif($f eq "TLS-SRP") {
- if($has_tls_srp) {
+ }
+
+ # We require a feature to not be present
+ if(!$why) {
+ for(@what) {
+ my $f = $_;
+ $f =~ s/\s//g;
+
+ if($f =~ /^!(.*)$/) {
+ if($1 eq "SSL") {
+ if(!$ssl_version) {
+ next;
+ }
+ }
+ elsif($1 eq "OpenSSL") {
+ if(!$has_openssl) {
+ next;
+ }
+ }
+ elsif($1 eq "GnuTLS") {
+ if(!$has_gnutls) {
+ next;
+ }
+ }
+ elsif($1 eq "NSS") {
+ if(!$has_nss) {
+ next;
+ }
+ }
+ elsif($1 eq "axTLS") {
+ if(!$has_axtls) {
+ next;
+ }
+ }
+ elsif($1 eq "WinSSL") {
+ if(!$has_winssl) {
+ next;
+ }
+ }
+ elsif($1 eq "DarwinSSL") {
+ if(!$has_darwinssl) {
+ next;
+ }
+ }
+ elsif($1 eq "TrackMemory") {
+ if(!$has_memory_tracking) {
+ next;
+ }
+ }
+ elsif($1 eq "large_file") {
+ if(!$large_file) {
+ next;
+ }
+ }
+ elsif($1 eq "idn") {
+ if(!$has_idn) {
+ next;
+ }
+ }
+ elsif($1 eq "ipv6") {
+ if(!$has_ipv6) {
+ next;
+ }
+ }
+ elsif($1 eq "unix-sockets") {
+ next if !$has_unix;
+ }
+ elsif($1 eq "libz") {
+ if(!$has_libz) {
+ next;
+ }
+ }
+ elsif($1 eq "NTLM") {
+ if(!$has_ntlm) {
+ next;
+ }
+ }
+ elsif($1 eq "NTLM_WB") {
+ if(!$has_ntlm_wb) {
+ next;
+ }
+ }
+ elsif($1 eq "SSPI") {
+ if(!$has_sspi) {
+ next;
+ }
+ }
+ elsif($1 eq "GSS-API") {
+ if(!$has_gssapi) {
+ next;
+ }
+ }
+ elsif($1 eq "Kerberos") {
+ if(!$has_kerberos) {
+ next;
+ }
+ }
+ elsif($1 eq "SPNEGO") {
+ if(!$has_spnego) {
+ next;
+ }
+ }
+ elsif($1 eq "getrlimit") {
+ if(!$has_getrlimit) {
+ next;
+ }
+ }
+ elsif($1 eq "crypto") {
+ if(!$has_crypto) {
+ next;
+ }
+ }
+ elsif($1 eq "TLS-SRP") {
+ if(!$has_tls_srp) {
+ next;
+ }
+ }
+ elsif($1 eq "Metalink") {
+ if(!$has_metalink) {
+ next;
+ }
+ }
+ else {
+ next;
+ }
+ }
+ else {
next;
}
- }
- elsif($f eq "socks") {
- next;
- }
- # See if this "feature" is in the list of supported protocols
- elsif (grep /^\Q$f\E$/i, @protocols) {
- next;
- }
- $why = "curl lacks $f support";
- last;
+ $why = "curl has $1 support";
+ last;
+ }
}
if(!$why) {
my @keywords = getpart("info", "keywords");
my $match;
my $k;
+
+ if(!$keywords[0]) {
+ $why = "missing the <keywords> section!";
+ }
+
for $k (@keywords) {
chomp $k;
if ($disabled_keywords{$k}) {
$teststat[$testnum]=$why; # store reason for this test case
if(!$short) {
- printf "test %03d SKIPPED: $why\n", $testnum;
+ if($skipped{$why} <= 3) {
+ # show only the first three skips for each reason
+ logmsg sprintf("test %04d SKIPPED: $why\n", $testnum);
+ }
}
timestampskippedevents($testnum);
return -1;
}
- logmsg sprintf("test %03d...", $testnum);
+ logmsg sprintf("test %04d...", $testnum) if(!$automakestyle);
# extract the reply data
my @reply = getpart("reply", "data");
my @replycheck = getpart("reply", "datacheck");
+ my %replyattr = getpartattr("reply", "data");
+ my %replycheckattr = getpartattr("reply", "datacheck");
+
if (@replycheck) {
# we use this file instead to check the final output against
- my %hash = getpartattr("reply", "datacheck");
- if($hash{'nonewline'}) {
+ if($replycheckattr{'nonewline'}) {
# Yes, we must cut off the final newline from the final line
# of the datacheck
chomp($replycheck[$#replycheck]);
}
+ if($replycheckattr{'mode'}) {
+ $replyattr{'mode'} = $replycheckattr{'mode'};
+ }
@reply=@replycheck;
}
# this is the valid protocol blurb curl should generate
my @protocol= fixarray ( getpart("verify", "protocol") );
+ # this is the valid protocol blurb curl should generate to a proxy
+ my @proxyprot = fixarray ( getpart("verify", "proxy") );
+
# redirected stdout/stderr to these files
$STDOUT="$LOGDIR/stdout$testnum";
$STDERR="$LOGDIR/stderr$testnum";
# name of the test
my @testname= getpart("client", "name");
-
- if(!$short) {
- my $name = $testname[0];
- $name =~ s/\n//g;
- logmsg "[$name]\n";
- }
+ my $testname = $testname[0];
+ $testname =~ s/\n//g;
+ logmsg "[$testname]\n" if(!$short);
if($listonly) {
timestampskippedevents($testnum);
chomp $tool;
}
- # remove server output logfiles
+ # remove server output logfile
unlink($SERVERIN);
unlink($SERVER2IN);
+ unlink($PROXYIN);
if(@ftpservercmd) {
# write the instructions to file
# there was no command given, use something silly
$cmd="-";
}
- if($curl_debug) {
+ if($has_memory_tracking) {
unlink($memdump);
}
my $CMDLINE;
my $cmdargs;
my $cmdtype = $cmdhash{'type'} || "default";
+ my $fail_due_event_based = $evbased;
if($cmdtype eq "perl") {
# run the command line prepended with "perl"
$cmdargs ="$cmd";
$tool=$CMDLINE;
$disablevalgrind=1;
}
+ elsif($cmdtype eq "shell") {
+ # run the command line prepended with "/bin/sh"
+ $cmdargs ="$cmd";
+ $CMDLINE = "/bin/sh ";
+ $tool=$CMDLINE;
+ $disablevalgrind=1;
+ }
elsif(!$tool) {
- # run curl, add --verbose for debug information output
+ # run curl, add suitable command line options
$cmd = "-1 ".$cmd if(exists $feature{"SSL"} && ($has_axtls));
my $inc="";
if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-include/)) {
- $inc = "--include ";
+ $inc = " --include";
}
- $cmdargs ="$out $inc--verbose --trace-time $cmd";
+ $cmdargs = "$out$inc ";
+ $cmdargs .= "--trace-ascii log/trace$testnum ";
+ $cmdargs .= "--trace-time ";
+ if($evbased) {
+ $cmdargs .= "--test-event ";
+ $fail_due_event_based--;
+ }
+ $cmdargs .= $cmd;
}
else {
$cmdargs = " $cmd"; # $cmd is the command line for the test file
}
if(! -f $CMDLINE) {
- print "The tool set in the test case for this: '$tool' does not exist\n";
+ logmsg "The tool set in the test case for this: '$tool' does not exist\n";
timestampskippedevents($testnum);
return -1;
}
$DBGCURL=$CMDLINE;
}
+ if($gdbthis) {
+ # gdb is incompatible with valgrind, so disable it when debugging
+ # Perhaps a better approach would be to run it under valgrind anyway
+ # with --db-attach=yes or --vgdb=yes.
+ $disablevalgrind=1;
+ }
+
+ if($fail_due_event_based) {
+ logmsg "This test cannot run event based\n";
+ return -1;
+ }
+
my @stdintest = getpart("client", "stdin");
if(@stdintest) {
my $stdinfile="$LOGDIR/stdin-for-$testnum";
+
+ my %hash = getpartattr("client", "stdin");
+ if($hash{'nonewline'}) {
+ # cut off the final newline from the final line of the stdin data
+ chomp($stdintest[$#stdintest]);
+ }
+
writearray($stdinfile, \@stdintest);
$cmdargs .= " <$stdinfile";
my $valgrindcmd = "$valgrind ";
$valgrindcmd .= "$valgrind_tool " if($valgrind_tool);
$valgrindcmd .= "--leak-check=yes ";
+ $valgrindcmd .= "--suppressions=$srcdir/valgrind.supp ";
+ # $valgrindcmd .= "--gen-suppressions=all ";
$valgrindcmd .= "--num-callers=16 ";
$valgrindcmd .= "${valgrind_logfile}=$LOGDIR/valgrind$testnum";
$CMDLINE = "$valgrindcmd $CMDLINE";
my @killservers;
foreach my $server (@killtestservers) {
chomp $server;
- if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
+ if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
# given a stunnel ssl server, also kill non-ssl underlying one
push @killservers, "${1}${2}";
}
- elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|))$/) {
+ elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|-unix|))$/) {
# given a non-ssl server, also kill stunnel piggybacking one
push @killservers, "${1}s${2}";
}
my $filemode=$hash{'mode'};
if($filemode && ($filemode eq "text") && $has_textaware) {
# text mode when running on windows: fix line endings
- map s/\r\n/\n/g, @actual;
+ map s/\r\n/\n/g, @validstdout;
+ map s/\n/\r\n/g, @validstdout;
}
if($hash{'nonewline'}) {
chomp($validstdout[$#validstdout]);
}
- $res = compare("stdout", \@actual, \@validstdout);
+ $res = compare($testnum, $testname, "stdout", \@actual, \@validstdout);
if($res) {
- # timestamp test result verification end
- $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
return 1;
}
$ok .= "s";
$ok .= "-"; # stdout not checked
}
- my %replyattr = getpartattr("reply", "data");
+ if(@protocol) {
+ # Verify the sent request
+ my @out = loadarray($SERVERIN);
+
+ # what to cut off from the live protocol sent by curl
+ my @strip = getpart("verify", "strip");
+
+ my @protstrip=@protocol;
+
+ # check if there's any attributes on the verify/protocol section
+ my %hash = getpartattr("verify", "protocol");
+
+ if($hash{'nonewline'}) {
+ # Yes, we must cut off the final newline from the final line
+ # of the protocol data
+ chomp($protstrip[$#protstrip]);
+ }
+
+ for(@strip) {
+ # strip off all lines that match the patterns from both arrays
+ chomp $_;
+ @out = striparray( $_, \@out);
+ @protstrip= striparray( $_, \@protstrip);
+ }
+
+ # what parts to cut off from the protocol
+ my @strippart = getpart("verify", "strippart");
+ my $strip;
+ for $strip (@strippart) {
+ chomp $strip;
+ for(@out) {
+ eval $strip;
+ }
+ }
+
+ $res = compare($testnum, $testname, "protocol", \@out, \@protstrip);
+ if($res) {
+ return 1;
+ }
+
+ $ok .= "p";
+
+ }
+ else {
+ $ok .= "-"; # protocol not checked
+ }
+
if(!$replyattr{'nocheck'} && (@reply || $replyattr{'sendzero'})) {
# verify the received data
my @out = loadarray($CURLOUT);
- my %hash = getpartattr("reply", "data");
# get the mode attribute
- my $filemode=$hash{'mode'};
+ my $filemode=$replyattr{'mode'};
if($filemode && ($filemode eq "text") && $has_textaware) {
# text mode when running on windows: fix line endings
- map s/\r\n/\n/g, @out;
+ map s/\r\n/\n/g, @reply;
+ map s/\n/\r\n/g, @reply;
}
- $res = compare("data", \@out, \@reply);
+ $res = compare($testnum, $testname, "data", \@out, \@reply);
if ($res) {
- # timestamp test result verification end
- $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
return 1;
}
$ok .= "d";
if(@upload) {
# verify uploaded data
my @out = loadarray("$LOGDIR/upload.$testnum");
- $res = compare("upload", \@out, \@upload);
+ $res = compare($testnum, $testname, "upload", \@out, \@upload);
if ($res) {
- # timestamp test result verification end
- $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
return 1;
}
$ok .= "u";
$ok .= "-"; # upload not checked
}
- if(@protocol) {
- # Verify the sent request
- my @out = loadarray($SERVERIN);
+ if(@proxyprot) {
+ # Verify the sent proxy request
+ my @out = loadarray($PROXYIN);
- # what to cut off from the live protocol sent by curl
+ # what to cut off from the live protocol sent by curl, we use the
+ # same rules as for <protocol>
my @strip = getpart("verify", "strip");
- my @protstrip=@protocol;
+ my @protstrip=@proxyprot;
# check if there's any attributes on the verify/protocol section
- my %hash = getpartattr("verify", "protocol");
+ my %hash = getpartattr("verify", "proxy");
if($hash{'nonewline'}) {
# Yes, we must cut off the final newline from the final line
}
}
- $res = compare("protocol", \@out, \@protstrip);
+ $res = compare($testnum, $testname, "proxy", \@out, \@protstrip);
if($res) {
- # timestamp test result verification end
- $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
return 1;
}
- $ok .= "p";
+ $ok .= "P";
}
else {
$ok .= "-"; # protocol not checked
}
- my @outfile=getpart("verify", "file");
- if(@outfile) {
- # we're supposed to verify a dynamically generated file!
- my %hash = getpartattr("verify", "file");
+ my $outputok;
+ for my $partsuffix (('', '1', '2', '3', '4')) {
+ my @outfile=getpart("verify", "file".$partsuffix);
+ if(@outfile || partexists("verify", "file".$partsuffix) ) {
+ # we're supposed to verify a dynamically generated file!
+ my %hash = getpartattr("verify", "file".$partsuffix);
- my $filename=$hash{'name'};
- if(!$filename) {
- logmsg "ERROR: section verify=>file has no name attribute\n";
- stopservers($verbose);
- # timestamp test result verification end
- $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
- return -1;
- }
- my @generated=loadarray($filename);
+ my $filename=$hash{'name'};
+ if(!$filename) {
+ logmsg "ERROR: section verify=>file$partsuffix ".
+ "has no name attribute\n";
+ stopservers($verbose);
+ # timestamp test result verification end
+ $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
+ return -1;
+ }
+ my @generated=loadarray($filename);
- # what parts to cut off from the file
- my @stripfile = getpart("verify", "stripfile");
+ # what parts to cut off from the file
+ my @stripfile = getpart("verify", "stripfile".$partsuffix);
- my $filemode=$hash{'mode'};
- if($filemode && ($filemode eq "text") && $has_textaware) {
- # text mode when running on windows means adding an extra
- # strip expression
- push @stripfile, "s/\r\n/\n/";
- }
+ my $filemode=$hash{'mode'};
+ if($filemode && ($filemode eq "text") && $has_textaware) {
+ # text mode when running on windows: fix line endings
+ map s/\r\n/\n/g, @outfile;
+ map s/\n/\r\n/g, @outfile;
+ }
- my $strip;
- for $strip (@stripfile) {
- chomp $strip;
- for(@generated) {
- eval $strip;
+ my $strip;
+ for $strip (@stripfile) {
+ chomp $strip;
+ my @newgen;
+ for(@generated) {
+ eval $strip;
+ if($_) {
+ push @newgen, $_;
+ }
+ }
+ # this is to get rid of array entries that vanished (zero
+ # length) because of replacements
+ @generated = @newgen;
}
- }
- @outfile = fixarray(@outfile);
+ @outfile = fixarray(@outfile);
- $res = compare("output", \@generated, \@outfile);
- if($res) {
- # timestamp test result verification end
- $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
- return 1;
- }
+ $res = compare($testnum, $testname, "output ($filename)",
+ \@generated, \@outfile);
+ if($res) {
+ return 1;
+ }
- $ok .= "o";
- }
- else {
- $ok .= "-"; # output not checked
+ $outputok = 1; # output checked
+ }
}
+ $ok .= ($outputok) ? "o" : "-"; # output checked or not
# accept multiple comma-separated error codes
my @splerr = split(/ *, */, $errorcode);
}
else {
if(!$short) {
- printf("\n%s returned $cmdres, when expecting %s\n",
- (!$tool)?"curl":$tool, $errorcode);
+ logmsg sprintf("\n%s returned $cmdres, when expecting %s\n",
+ (!$tool)?"curl":$tool, $errorcode);
}
logmsg " exit FAILED\n";
# timestamp test result verification end
return 1;
}
- if($curl_debug) {
+ if($has_memory_tracking) {
if(! -f $memdump) {
- logmsg "\n** ALERT! memory debugging with no output file?\n"
+ logmsg "\n** ALERT! memory tracking with no output file?\n"
if(!$cmdtype eq "perl");
}
else {
}
my @e = valgrindparse($srcdir, $feature{'SSL'}, "$LOGDIR/$vgfile");
if(@e && $e[0]) {
- logmsg " valgrind ERROR ";
- logmsg @e;
+ if($automakestyle) {
+ logmsg "FAIL: $testnum - $testname - valgrind\n";
+ }
+ else {
+ logmsg " valgrind ERROR ";
+ logmsg @e;
+ }
# timestamp test result verification end
$timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
return 1;
else {
$ok .= "-"; # valgrind not checked
}
+ # add 'E' for event-based
+ $ok .= $evbased ? "E" : "-";
logmsg "$ok " if(!$short);
my $left=sprintf("remaining: %02d:%02d",
$estleft/60,
$estleft%60);
- printf "OK (%-3d out of %-3d, %s)\n", $count, $total, $left;
+
+ if(!$automakestyle) {
+ logmsg sprintf("OK (%-3d out of %-3d, %s)\n", $count, $total, $left);
+ }
+ else {
+ logmsg "PASS: $testnum - $testname\n";
+ }
# the test succeeded, remove all log files
if(!$keepoutfiles) {
$what =~ s/[^a-z0-9-]//g;
my $certfile;
- if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
+ if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
$certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem';
}
}
}
elsif($what eq "ftp2") {
- if($torture && $run{'ftp2'} &&
+ if($torture && $run{'ftp2'} &&
!responsive_pingpong_server("ftp", "2", $verbose)) {
stopserver('ftp2');
}
if($pid <= 0) {
return "failed starting GOPHER server";
}
- printf ("* pid gopher => %d %d\n", $pid, $pid2) if($verbose);
+ logmsg sprintf ("* pid gopher => %d %d\n", $pid, $pid2)
+ if($verbose);
$run{'gopher'}="$pid $pid2";
}
}
if($pid <= 0) {
return "failed starting HTTP server";
}
- printf ("* pid http => %d %d\n", $pid, $pid2) if($verbose);
+ logmsg sprintf ("* pid http => %d %d\n", $pid, $pid2)
+ if($verbose);
$run{'http'}="$pid $pid2";
}
}
+ elsif($what eq "http-proxy") {
+ if($torture && $run{'http-proxy'} &&
+ !responsive_http_server("http", $verbose, "proxy",
+ $HTTPPROXYPORT)) {
+ stopserver('http-proxy');
+ }
+ if(!$run{'http-proxy'}) {
+ ($pid, $pid2) = runhttpserver("http", $verbose, "proxy",
+ $HTTPPROXYPORT);
+ if($pid <= 0) {
+ return "failed starting HTTP-proxy server";
+ }
+ logmsg sprintf ("* pid http-proxy => %d %d\n", $pid, $pid2)
+ if($verbose);
+ $run{'http-proxy'}="$pid $pid2";
+ }
+ }
elsif($what eq "http-ipv6") {
if($torture && $run{'http-ipv6'} &&
- !responsive_http_server("http", $verbose, "IPv6", $HTTP6PORT)) {
+ !responsive_http_server("http", $verbose, "ipv6", $HTTP6PORT)) {
stopserver('http-ipv6');
}
if(!$run{'http-ipv6'}) {
- ($pid, $pid2) = runhttpserver("http", $verbose, "IPv6",
+ ($pid, $pid2) = runhttpserver("http", $verbose, "ipv6",
$HTTP6PORT);
if($pid <= 0) {
return "failed starting HTTP-IPv6 server";
$run{'http-ipv6'}="$pid $pid2";
}
}
+ elsif($what eq "http-pipe") {
+ if($torture && $run{'http-pipe'} &&
+ !responsive_http_server("http", $verbose, "pipe",
+ $HTTPPIPEPORT)) {
+ stopserver('http-pipe');
+ }
+ if(!$run{'http-pipe'}) {
+ ($pid, $pid2) = runhttpserver("http", $verbose, "pipe",
+ $HTTPPIPEPORT);
+ if($pid <= 0) {
+ return "failed starting HTTP-pipe server";
+ }
+ logmsg sprintf ("* pid http-pipe => %d %d\n", $pid, $pid2)
+ if($verbose);
+ $run{'http-pipe'}="$pid $pid2";
+ }
+ }
elsif($what eq "rtsp") {
if($torture && $run{'rtsp'} &&
!responsive_rtsp_server($verbose)) {
}
elsif($what eq "rtsp-ipv6") {
if($torture && $run{'rtsp-ipv6'} &&
- !responsive_rtsp_server($verbose, "IPv6")) {
+ !responsive_rtsp_server($verbose, "ipv6")) {
stopserver('rtsp-ipv6');
}
if(!$run{'rtsp-ipv6'}) {
- ($pid, $pid2) = runrtspserver($verbose, "IPv6");
+ ($pid, $pid2) = runrtspserver($verbose, "ipv6");
if($pid <= 0) {
return "failed starting RTSP-IPv6 server";
}
return "no gnutls-serv";
}
if($torture && $run{'httptls-ipv6'} &&
- !responsive_httptls_server($verbose, "IPv6")) {
+ !responsive_httptls_server($verbose, "ipv6")) {
stopserver('httptls-ipv6');
}
if(!$run{'httptls-ipv6'}) {
- ($pid, $pid2) = runhttptlsserver($verbose, "IPv6");
+ ($pid, $pid2) = runhttptlsserver($verbose, "ipv6");
if($pid <= 0) {
return "failed starting HTTPTLS-IPv6 server (gnutls-serv)";
}
}
elsif($what eq "tftp-ipv6") {
if($torture && $run{'tftp-ipv6'} &&
- !responsive_tftp_server("", $verbose, "IPv6")) {
+ !responsive_tftp_server("", $verbose, "ipv6")) {
stopserver('tftp-ipv6');
}
if(!$run{'tftp-ipv6'}) {
- ($pid, $pid2) = runtftpserver("", $verbose, "IPv6");
+ ($pid, $pid2) = runtftpserver("", $verbose, "ipv6");
if($pid <= 0) {
return "failed starting TFTP-IPv6 server";
}
}
}
}
+ elsif($what eq "http-unix") {
+ if($torture && $run{'http-unix'} &&
+ !responsive_http_server("http", $verbose, "unix", $HTTPUNIXPATH)) {
+ stopserver('http-unix');
+ }
+ if(!$run{'http-unix'}) {
+ ($pid, $pid2) = runhttpserver("http", $verbose, "unix",
+ $HTTPUNIXPATH);
+ if($pid <= 0) {
+ return "failed starting HTTP-unix server";
+ }
+ logmsg sprintf("* pid http-unix => %d %d\n", $pid, $pid2)
+ if($verbose);
+ $run{'http-unix'}="$pid $pid2";
+ }
+ }
elsif($what eq "none") {
logmsg "* starts no server\n" if ($verbose);
}
return "curl lacks $tlsext support";
}
else {
- return "curl lacks $server support";
+ return "curl lacks $server server support";
}
}
}
$DBGCURL=$CURL=$ARGV[1];
shift @ARGV;
}
+ elsif ($ARGV[0] eq "-vc") {
+ # use this path to a curl used to verify servers
+
+ # Particularly useful when you introduce a crashing bug somewhere in
+ # the development version as then it won't be able to run any tests
+ # since it can't verify the servers!
+
+ $VCURL=$ARGV[1];
+ shift @ARGV;
+ }
elsif ($ARGV[0] eq "-d") {
# have the servers display protocol output
$debugprotocol=1;
}
- elsif ($ARGV[0] eq "-f") {
- # run fork-servers, which makes the server fork for all new
- # connections This is NOT what you wanna do without knowing exactly
- # why and for what
- $forkserver=1;
- }
elsif ($ARGV[0] eq "-g") {
# run this test with gdb
$gdbthis=1;
# short output
$short=1;
}
+ elsif($ARGV[0] eq "-am") {
+ # automake-style output
+ $short=1;
+ $automakestyle=1;
+ }
elsif($ARGV[0] eq "-n") {
# no valgrind
undef $valgrind;
# continue anyway, even if a test fail
$anyway=1;
}
+ elsif($ARGV[0] eq "-e") {
+ # run the tests cases event based if possible
+ $run_event_based=1;
+ }
elsif($ARGV[0] eq "-p") {
$postmortem=1;
}
-r run time statistics
-rf full run time statistics
-s short output
+ -am automake style output PASS/FAIL: [number] [name]
-t[N] torture (simulate memory alloc failures); N means fail Nth alloc
-v verbose output
+ -vc path use this curl only to verify the existing servers
[num] like "5 6 9" or " 5 to 22 " to run those tests only
[!num] like "!5 !6 !9" to disable those tests
[keyword] like "IPv6" to select only tests containing the key word
if($c eq "#! /") {
# A shell script. This is typically when built with libtool,
$libtool = 1;
- $gdb = "libtool --mode=execute gdb";
+ $gdb = "../libtool --mode=execute gdb";
}
}
$GOPHER6PORT = $base++; # Gopher IPv6 server port
$HTTPTLSPORT = $base++; # HTTP TLS (non-stunnel) server port
$HTTPTLS6PORT = $base++; # HTTP TLS (non-stunnel) IPv6 server port
+$HTTPPROXYPORT = $base++; # HTTP proxy port, when using CONNECT
+$HTTPPIPEPORT = $base++; # HTTP pipelining port
+$HTTPUNIXPATH = 'http.sock'; # HTTP server Unix domain socket path
#######################################################################
# clear and create logging directory:
}
#######################################################################
-# Fetch all disabled tests
+# Fetch all disabled tests, if there are any
#
-open(D, "<$TESTDIR/DISABLED");
-while(<D>) {
- if(/^ *\#/) {
- # allow comments
- next;
- }
- if($_ =~ /(\d+)/) {
- $disabled{$1}=$1; # disable this test number
+if(open(D, "<$TESTDIR/DISABLED")) {
+ while(<D>) {
+ if(/^ *\#/) {
+ # allow comments
+ next;
+ }
+ if($_ =~ /(\d+)/) {
+ $disabled{$1}=$1; # disable this test number
+ }
}
+ close(D);
}
-close(D);
#######################################################################
# If 'all' tests are requested, find out all test numbers
$TESTCASES .= " $n";
}
}
+else {
+ my $verified="";
+ map {
+ if (-e "$TESTDIR/test$_") {
+ $verified.="$_ ";
+ }
+ } split(" ", $TESTCASES);
+ if($verified eq "") {
+ print "No existing test cases were specified\n";
+ exit;
+ }
+ $TESTCASES = $verified;
+}
#######################################################################
# Start the command line log
if(($log =~ /^netrc\d+/) && ($log !~ /^netrc$testnum/)) {
next; # skip netrcNnn of other tests
}
+ if(($log =~ /^trace\d+/) && ($log !~ /^trace$testnum/)) {
+ next; # skip traceNnn of other tests
+ }
if(($log =~ /^valgrind\d+/) && ($log !~ /^valgrind$testnum(\..*|)$/)) {
next; # skip valgrindNnn of other tests
}
$lasttest = $testnum if($testnum > $lasttest);
$count++;
- my $error = singletest($testnum, $count, scalar(@at));
+ my $error = singletest($run_event_based, $testnum, $count, scalar(@at));
if($error < 0) {
# not a test we can run
next;
# now show all test case numbers that had this reason for being
# skipped
my $c=0;
+ my $max = 9;
for(0 .. scalar @teststat) {
my $t = $_;
if($teststat[$_] && ($teststat[$_] eq $r)) {
- logmsg ", " if($c);
- logmsg $_;
+ if($c < $max) {
+ logmsg ", " if($c);
+ logmsg $_;
+ }
$c++;
}
}
+ if($c > $max) {
+ logmsg " and ".($c-$max)." more";
+ }
logmsg ")\n";
}
}