diff --git a/tests/README b/tests/README index 7c334c9c6..64348004b 100644 --- a/tests/README +++ b/tests/README @@ -13,6 +13,9 @@ Run: 'make test'. This invokes the 'runtests.sh' shell script. Edit the top variables of that script in case you have some specific needs. + The script breaks on the first test that doesn't do OK. Run the script + with -v for more verbose output. + Logs: All logs are generated in the logs/ subdirctory (it is emtpied first in the runtests.sh script) @@ -29,4 +32,12 @@ Data: httpN.txt: the full dump of the HTTP protocol communication that curl is expected to use when performing this test - replyN.txt: the full dump the server should reply to curl for this test + replyN.txt: the full dump the server should reply to curl for this test. + If the final result that curl should've got is not in this + file, you can instead name the file replyN0001.txt. This enables + you to fiddle more. ;-) + +FIX: + + * Make httpserver.pl work when we PUT without Content-Length: + diff --git a/tests/httpserver.pl b/tests/httpserver.pl index 3d6938513..6ece59630 100755 --- a/tests/httpserver.pl +++ b/tests/httpserver.pl @@ -1,22 +1,31 @@ #!/usr/bin/perl use Socket; use Carp; +use FileHandle; sub spawn; # forward declaration sub logmsg { #print "$0 $$: @_ at ", scalar localtime, "\n" } -my $port = shift || $ARGV[0]; +my $port = $ARGV[0]; my $proto = getprotobyname('tcp'); $port = $1 if $port =~ /(\d+)/; # untaint port number +if($ARGV[1] =~ /^ftp$/i) { + $protocol="FTP"; +} +else { + $protocol="HTTP"; +} + + socket(Server, PF_INET, SOCK_STREAM, $proto)|| die "socket: $!"; setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt: $!"; bind(Server, sockaddr_in($port, INADDR_ANY))|| die "bind: $!"; listen(Server,SOMAXCONN) || die "listen: $!"; -logmsg "server started on port $port"; +print "$protocol server started on port $port\n"; open(PID, ">.server.pid"); print PID $$; @@ -46,8 +55,53 @@ for ( $waitedpid = 0; # this code is forked and run spawn sub { my ($request, $path, $ver, $left, $cl); + + if($protocol eq "FTP") { + + # < 220 pm1 FTP server (SunOS 5.7) ready. + # > USER anonymous + # < 331 Guest login ok, send ident as password. + # > PASS curl_by_daniel@haxx.se + # < 230 Guest login ok, access restrictions apply. + # * We have successfully logged in + # * Connected to pm1 (193.15.23.1) + # > PASV + # < 227 Entering Passive Mode (193,15,23,1,231,59) + # * Connecting to pm1 (193.15.23.1) port 59195 + # > TYPE A + # < 200 Type set to A. + # > LIST + # < 150 ASCII data connection for /bin/ls (193.15.23.1,59196) (0 bytes). + # * Getting file with size: -1 + + print "220-running the curl suite test server\r\n", + "220-running the curl suite test server\r\n", + "220 running the curl suite test server\r\n"; + + STDOUT->autoflush(1); + + while(1) { + + last unless defined ($_ = ); + + # Remove trailing CRLF. + s/[\n\r]+$//; + + unless (m/^([A-Z]{3,4})\s?(.*)/i) + { + print STDERR + "badly formed command received: ".$_; + exit 0; + } + + print STDERR "GOT: $_\n"; + } + exit; + } + # otherwise, we're doing HTTP + while() { - if($_ =~ /(GET|POST|HEAD) (.*) HTTP\/1.(\d)/) { + if($_ =~ /([A-Z]*) (.*) HTTP\/1.(\d)/) { $request=$1; $path=$2; $ver=$3; @@ -68,7 +122,7 @@ for ( $waitedpid = 0; if(!$left && ($_ eq "\r\n") or ($_ eq "")) { - if($request eq "POST") { + if($request =~ /^(POST|PUT)$/) { $left=$cl; } else { diff --git a/tests/runtests.pl b/tests/runtests.pl new file mode 100755 index 000000000..2eeb8bbf7 --- /dev/null +++ b/tests/runtests.pl @@ -0,0 +1,275 @@ +#!/usr/bin/perl +# +# Main curl test script, in perl to run on more platforms +# +####################################################################### +# These should be the only variables that might be needed to get edited: + +$HOSTIP="127.0.0.1"; +$HOSTPORT=8999; +$CURL="../src/curl"; +$LOGDIR="log"; +$TESTDIR="data"; +$SERVERIN="$LOGDIR/server.input"; +$CURLOUT="$LOGDIR/curl.out"; + +# Normally, all test cases should be run, but at times it is handy to +# simply run a particular one: +$TESTCASES="all"; + +# To run specific test cases, set them like: +# $TESTCASES="1 2 3 7 8"; + +####################################################################### +# No variables below this point should need to be modified +# + +$PIDFILE=".server.pid"; + +sub stopserver { + # check for pidfile + if ( -f $PIDFILE ) { + $PID=`cat $PIDFILE`; + kill (9, $PID); # die! + unlink $PIDFILE; # server is killed + } +} + +sub runserver { + # check for pidfile + if ( -f $PIDFILE ) { + $PID=`cat $PIDFILE`; + if ($PID ne "" && kill(0, $PID)) { + $STATUS="httpd (pid $PID) running"; + $RUNNING=1; + } + else { + $STATUS="httpd (pid $PID?) not running"; + $RUNNING=0; + } + } + else { + $STATUS="httpd (no pid file) not running"; + $RUNNING=0; + } + + if ($RUNNING != 1) { + system("perl ./httpserver.pl $HOSTPORT &"); + sleep 1; # give it a little time to start + } + else { + print "$STATUS\n"; + + # verify that our server is one one running on this port: + $data=`$CURL --silent -i $HOSTIP:$HOSTPORT/verifiedserver`; + + if ( $data !~ /WE ROOLZ/ ) { + print "Another HTTP server is running on port $HOSTPORT\n", + "Edit runtests.pl to use another port and rerun the test script\n"; + exit; + } + + print "The running HTTP server has been verified to be our server\n"; + } +} + +sub filteroff { + my $infile=$_[0]; + my $filter=$_[1]; + my $ofile=$_[2]; + + open(IN, "<$infile") + || return 1; + + open(OUT, ">$ofile") + || return 1; + + # print "FILTER: off $filter from $infile to $ofile\n"; + + # system("egrep -v \"$strip\" < $first > $LOGDIR/generated.tmp"); + while() { + $_ =~ s/$filter//; + print OUT $_; + } + close(IN); + close(OUT); + return 0; +} +sub compare { + # filter off the 4 pattern before compare! + + my $first=$_[0]; + my $sec=$_[1]; + my $text=$_[2]; + my $strip=$_[3]; + + if ($strip ne "") { + filteroff($first, $strip, "$LOGDIR/generated.tmp"); + filteroff($sec, $strip, "$LOGDIR/stored.tmp"); +# system("egrep -v \"$strip\" < $sec > $LOGDIR/stored.tmp"); + + $first="$LOGDIR/generated.tmp"; + $sec="$LOGDIR/stored.tmp"; + } + + $res = system("cmp $first $sec"); + $res /= 256; + if ($res != 0) { + print " $text FAILED\n"; + return 1; + } + + print " $text OK\n"; + return 0; +} + +sub displaydata { + my $version=`$CURL -V`; + my $hostname=`hostname`; + my $hosttype=`uname -a`; + + print "Running tests on:\n", + "$version", + "host $hostname", + "system $hosttype"; +} + +sub singletest { + my $NUMBER=$_[0]; + my $REPLY="${TESTDIR}/reply${NUMBER}.txt"; + + if ( -f "$TESTDIR/reply${NUMBER}0001.txt" ) { + # we use this file instead to check the final output against + $REPLY="$TESTDIR/reply${NUMBER}0001.txt"; + } + + # curl command to run + $CURLCMD="$TESTDIR/command$NUMBER.txt"; + + # this is the valid HTTP we should generate + $HTTP="$TESTDIR/http$NUMBER.txt"; + + # name of the test + $DESC=`cat $TESTDIR/name$NUMBER.txt | tr -d '\012'`; + + # redirected stdout here + $STDOUT="$LOGDIR/stdout$NUMBER"; + + # if this file exist, we verify that the stdout contained this: + $VALIDOUT="$TESTDIR/stdout$NUMBER.txt"; + + print "test $NUMBER... [$DESC]\n"; + + # get the command line options to use + + open(COMMAND, "<$CURLCMD"); + $cmd=; + chomp $cmd; + close(COMMAND); + + # make some nice replace operations + $cmd =~ s/%HOSTIP/$HOSTIP/g; + $cmd =~ s/%HOSTPORT/$HOSTPORT/g; + $cmd =~ s/%HOSTNAME/$HOSTNAME/g; + + # run curl, add -v for debug information output + $CMDLINE="$CURL --output $CURLOUT --include --silent $cmd >$STDOUT"; + + if($verbose) { + print "$CMDLINE\n"; + } + + # run the command line we built + $res = system("$CMDLINE"); + $res /= 256; + + if ($res != 0) { + print "Failed to invoke curl for test $NUMBER\n"; + } + else { + # verify the received data + $res = compare($CURLOUT, $REPLY, "data"); + $res /= 256; + + if ($res) { + exit; + } + + # verify the sent request + $res = compare($SERVERIN, $HTTP, "http", + "^(User-Agent:|--curl|Content-Type: multipart/form-data; boundary=).*\r\n"); + $res /= 256; + + # The strip pattern above is for stripping off User-Agent: since + # that'll be different in all versions, and the lines in a + # RFC1876-post that are randomly generated and therefore are doomed to + # always differ! + + if($res) { + exit; + } + + if ( -r "$VALIDOUT" ) { + + $res = compare($STDOUT, $VALIDOUT, "stdout"); + $res /= 256; + if($res) { + exit; + } + } + + # remove the stdout file + unlink("$STDOUT"); + + } + + return 0; +} + + +####################################################################### +# Check options to this test program +# + +if ($ARGV[0] eq "-v") { + $verbose=1; +} + +####################################################################### +# Output curl version and host info being tested +# + +displaydata(); + +####################################################################### +# remove and recreate logging directory: +# +system("rm -rf $LOGDIR"); +mkdir("$LOGDIR", 0777); + +####################################################################### +# First, start the TCP server +# + +runserver(); + +####################################################################### +# The main test-loop +# + +if ( $TESTCASES eq "all") { + $TESTCASES=`ls -1 $TESTDIR/command*.txt | sed -e 's/[a-z\/\.]*//g' | sort -n`; +} + +foreach $testnum (split(" ", $TESTCASES)) { + + singletest($testnum); + + # loop for next test +} + +####################################################################### +# Tests done, stop the server +# + +stopserver(); diff --git a/tests/runtests.sh b/tests/runtests.sh deleted file mode 100755 index dba912978..000000000 --- a/tests/runtests.sh +++ /dev/null @@ -1,220 +0,0 @@ -#!/bin/sh -# -# Main curl test script -# -####################################################################### -# These should be the only variables that might be needed to get edited: - -HOSTIP=127.0.0.1 -HOSTPORT=8999 -CURL=../src/curl -LOGDIR=log -SERVERIN=$LOGDIR/server.input -CURLOUT=$LOGDIR/curl.out -NC=nc - -# Normally, all test cases should be run, but at times it is handy to -# simply run a particular one: -TESTCASES=all - -# To run specific test cases, set them like: -# TESTCASES="1 2 3 7 8" - -####################################################################### -# No variables below this point should need to be modified -# - -PIDFILE=".server.pid" - -stopserver() { - # check for pidfile - if [ -f $PIDFILE ] ; then - PID=`cat $PIDFILE` - kill -9 $PID - rm -f $PIDFILE # server is killed - fi -} - -runserver () { - # check for pidfile - if [ -f $PIDFILE ] ; then - PID=`cat $PIDFILE` - if [ "x$PID" != "x" ] && kill -0 $PID 2>/dev/null ; then - STATUS="httpd (pid $PID) running" - RUNNING=1 - else - STATUS="httpd (pid $PID?) not running" - RUNNING=0 - fi - else - STATUS="httpd (no pid file) not running" - RUNNING=0 - fi - - if [ $RUNNING != "1" ]; then - ./httpserver.pl $HOSTPORT & - sleep 1 # give it a little time to start - else - echo $STATUS - - # verify that our server is one one running on this port: - data=`$CURL --silent -i $HOSTIP:$HOSTPORT/verifiedserver`; - - if { echo $data | grep -v "WE ROOLZ" >/dev/null 2>&1; } then - echo "Another HTTP server is running on port $HOSTPORT" - echo "Edit runtests.sh to use another port and rerun the test script" - exit - fi - - echo "The running HTTP server has been verified to be our test server" - - fi -} - -compare () { - # filter off the $4 pattern before compare! - - first="$1" - sec="$2" - text="$3" - strip="$4" - - if test -n "$strip"; then - egrep -v "$strip" < $first > $LOGDIR/generated.tmp - egrep -v "$strip" < $sec > $LOGDIR/stored.tmp - - first="$LOGDIR/generated.tmp" - sec="$LOGDIR/stored.tmp" - fi - - cmp $first $sec - if [ $? != "0" ]; then - echo " $text FAILED" - return 1 - else - echo " $text OK" - return 0 - fi -} - -singletest () -{ - NUMBER="$1" - - REPLY=data/reply$NUMBER.txt - CURLCMD=data/command$NUMBER.txt - HTTP=data/http$NUMBER.txt - DESC=`cat data/name$NUMBER.txt | tr -d '\012'` - - echo "test $NUMBER... [$DESC]" - - # get the command line options to use - cmd=`sed -e "s/%HOSTIP/$HOSTIP/g" \ - -e "s/%HOSTPORT/$HOSTPORT/g" \ - -e "s/%HOSTNAME/$HOSTNAME/g" <$CURLCMD ` - - # run curl - CMDLINE="$CURL -o $CURLOUT -i --silent $cmd" - - if test -n "$verbose"; then - echo "$CMDLINE" - fi - - # we do it the eval way to deal with quotes and similar stuff - eval $CMDLINE - - if [ $? != "0" ]; then - echo "Failed to invoke curl for test $NUMBER" - else - # when curl is done, the server has closed down as well - - # verify the received data - compare $CURLOUT $REPLY " fetch" - - if [ $? != "0" ]; then - exit; - fi - - # verify the sent request - compare $SERVERIN $HTTP " command" \ - "(User-Agent:|^--curl|Content-Type: multipart/form-data; boundary=)" - - # - # The strip pattern above is for stripping off User-Agent: since that'll - # be different in all versions, and the lines in a RFC1876-post that are - # randomly generated and therefore are doomed to always differ! - # - - - if [ $? != "0" ]; then - exit; - fi - fi - - return 0 -} - - -####################################################################### -# Check options to this test program -# - -if test "$1" = "-v"; then - verbose="1" -fi - -if test -n "$NEWSETUP"; then - - ####################################################################### - # Make sure the Host: lines are correct for this setup - # - - HOST="$HOSTIP:$HOSTPORT" - for test in data/http*.txt; do - sed -e "s/Host: \([0-9.:]*\)/Host: $HOST/g" < $test > $test.tmp - mv $test.tmp $test - done -fi - -####################################################################### -# Output curl version being tested -# -VERSION=`$CURL -V` -HOSTNAME=`hostname` - -echo "Running tests on:" -echo $VERSION -echo "host $HOSTNAME" - -####################################################################### -# remove and recreate logging directory: -# -rm -rf $LOGDIR -mkdir $LOGDIR - -####################################################################### -# First, start the TCP server -# - -runserver - -####################################################################### -# The main test-loop -# - -if [ x$TESTCASES = xall ]; then - TESTCASES=`ls -1 data/command*.txt | sed -e 's/[a-z\/\.]*//g'` -fi - -for NUMBER in $TESTCASES; do - - singletest $NUMBER - - # loop for next test -done - -####################################################################### -# Tests done, stop server -# - -stopserver