diff options
author | sumedh <sumedh@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-07-07 17:45:52 +0000 |
---|---|---|
committer | sumedh <sumedh@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-07-07 17:45:52 +0000 |
commit | a83e1233baf57356418c4dc67f85eac52ef66bbe (patch) | |
tree | bc6a256cc705ef8ae87e0611bc304354e0376039 /apps/JAWS/clients/WebSTONE/bin | |
parent | 727c757eec790064b77fda081c3daa1df509fc7f (diff) | |
download | ATCD-a83e1233baf57356418c4dc67f85eac52ef66bbe.tar.gz |
Created WebSTONE bin
Diffstat (limited to 'apps/JAWS/clients/WebSTONE/bin')
21 files changed, 1487 insertions, 0 deletions
diff --git a/apps/JAWS/clients/WebSTONE/bin/WebStone-common.pl b/apps/JAWS/clients/WebSTONE/bin/WebStone-common.pl new file mode 100755 index 00000000000..0e3ddd80ceb --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/WebStone-common.pl @@ -0,0 +1,61 @@ +#!/pkg/gnu/bin//perl5 +# + +1; + +sub show_model { + $model = `head -1 $wd/conf/filelist`; + $model =~ s/\#//; + ( $model ) = split(':', $model); + + print CLIENT <<EOF +<P><STRONG> +<A HREF=\"$wd/bin/WebStone-setup.pl\">$model +</A></STRONG> +EOF + ; +} + +sub html_begin { + + ( $title ) = @_; + + close(STDOUT); + open(STDOUT, ">&CLIENT"); + close(STDERR); + open(STDERR, ">&CLIENT"); + + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>WebStone $title</TITLE> +<A HREF="$wd/doc/WebStone.html"> +<IMG SRC="$wd/doc/webstone.gif" ALT="WebStone" BORDER=0 ></A> +<H1>World Wide Web Server Benchmarking</H1> +<DL> +<DT><EM>If you have any questions, please read the +<A HREF="$wd/doc/FAQ-webstone.html">WebStone FAQ</A>.</EM> +<HR> +EOF + ; + +} + +sub html_end { + + print CLIENT <<EOF +<HR> +<ADDRESS><A HREF="$wd/doc/LICENSE.html">copyright 1995 Silicon Graphics</A> +</ADDRESS> +</BODY> +</HTML> +EOF + ; + + close(STDERR); + close(STDOUT); + open(STDOUT); + open(STDERR); +} + +# end diff --git a/apps/JAWS/clients/WebSTONE/bin/WebStone-manage.pl b/apps/JAWS/clients/WebSTONE/bin/WebStone-manage.pl new file mode 100755 index 00000000000..e9d28e8fecf --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/WebStone-manage.pl @@ -0,0 +1,31 @@ +#!/pkg/gnu/bin//perl5 +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +html_begin("Administration"); + +$runsdir = "$wd/bin/runs"; +$thelength = length($runsdir) + 10; +$oldrunsdir = $runsdir; +$oldfilelist = "$wd/conf/filelist"; + +print CLIENT <<EOF +<FORM METHOD="POST" ACTION="$wd/bin/killbench.pl"> +<H3>Clean up stray WebStone processes</H3> +<INPUT TYPE="SUBMIT" VALUE="Kill"> +</FORM> + +<HR> +<FORM METHOD="POST" ACTION="$wd/bin/move-runs.pl"> +<H3>Move Results Directory to:</H3> +<INPUT TYPE=TEXT NAME=runsdir SIZE=$thelength VALUE=$runsdir> +<INPUT TYPE="SUBMIT" VALUE="Move Directory"> +</FORM> +EOF + ; + +html_end(); + +# end diff --git a/apps/JAWS/clients/WebSTONE/bin/WebStone-run.pl b/apps/JAWS/clients/WebSTONE/bin/WebStone-run.pl new file mode 100755 index 00000000000..716cebfa602 --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/WebStone-run.pl @@ -0,0 +1,37 @@ +#!/pkg/gnu/bin//perl5 +# + +$testbed = "conf/testbed"; + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +html_begin("Run"); + +print CLIENT <<EOF +<H3><CENTER><A HREF="WebStone-setup.pl">Edit Configuration</A> +</CENTER></H3> +EOF + ; + +&show_model(); +print CLIENT "<PRE>"; + +open(FILEHANDLE, $testbed); +while (<FILEHANDLE>) { + (/^\#/) || print CLIENT $_; +} +close(FILEHANDLE); + +print CLIENT <<EOF +</PRE> +<CENTER> +<FORM METHOD=POST ACTION="http://localhost:$html_port$wd/bin/runbench.pl"> +<INPUT TYPE="submit" VALUE="Run WebStone"> +</CENTER> +EOF + ; + +html_end(); + +# end diff --git a/apps/JAWS/clients/WebSTONE/bin/WebStone-setup.pl b/apps/JAWS/clients/WebSTONE/bin/WebStone-setup.pl new file mode 100755 index 00000000000..107e1d94890 --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/WebStone-setup.pl @@ -0,0 +1,95 @@ +#!/pkg/gnu/bin//perl5 +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +@keylist = (); + +html_begin("Setup"); + +show_model(); + +print CLIENT <<EOF +<FORM METHOD="POST" ACTION="$wd/bin/write-testbed.pl"> +EOF + ; + +&gettestbed(); +&getconfig(); + +print CLIENT <<EOF +</DL> +<P><INPUT TYPE="SUBMIT" VALUE="Write Configuration"> +</FORM> + +<HR> +<FORM METHOD="POST" ACTION="$wd/bin/move-filelist.pl"> +<H3>Choose a Web site model:</H3> +<DL> +EOF + ; + +for $key (sort(keys %filelist)) { + print CLIENT "<DD><INPUT TYPE=RADIO NAME=filelist "; + if ($key eq "filelist") { + print CLIENT " CHECKED "; + } + print CLIENT " VALUE=\"$wd/conf/$key\"> $key: $filelist{$key}"; +} + +print CLIENT <<EOF +</DL> +<INPUT TYPE="SUBMIT" VALUE="Set Workload"> + +EOF + ; + +html_end(); + +# end of main program + +sub gettestbed { + open(TESTBED, "$wd/conf/testbed"); + while (<TESTBED>) { + if (/^\#|^(\w)*$/) { # do nothing + } + else { + ( $textvalue, $thevalue ) = split( '=', $_ ); + ( $thevalue ) = split( '#', $thevalue); + $testbed{$textvalue} = $thevalue; + push(@keylist, $textvalue); + } + } + close(TESTBED); + + open(HELPFILE, "$wd/doc/testbed.help"); + while (<HELPFILE>) { + ( $key, $textvalue ) = split( ':', $_ ); + $helptext{$key} = $textvalue; + } + close(HELPFILE); + + foreach $key (@keylist) { + print CLIENT "<P><DT>$helptext{$key}"; + $thesize = length($testbed{$key}) + 5; + print CLIENT "<DD>$key <INPUT TYPE=TEXT NAME=$key "; + print CLIENT "SIZE=$thesize VALUE=$testbed{$key}>\n"; + } +} + +sub getconfig { + opendir(CONF, "$wd/conf") || die "open $wd/conf: $!"; + %filelist = ""; + foreach $file (sort readdir(CONF)) { + if ( $file =~ /^filelist.*/ ) { + $headtext = `head -1 $wd/conf/$file`; + $headtext =~ s/\#//; + ( $headtext ) = split(':', $headtext); + $filelist{$file} = $headtext; + } + } + closedir(CONF); +} + +# end diff --git a/apps/JAWS/clients/WebSTONE/bin/checkfilelist b/apps/JAWS/clients/WebSTONE/bin/checkfilelist new file mode 100755 index 00000000000..4cc2d11c49e --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/checkfilelist @@ -0,0 +1,35 @@ +#! /bin/sh + +# +# NAME +# checkfilelist - try retrieving files from server +# +# SYNOPSIS +# checkfilelist servername portno filelist +# +# + +if test "$#" -lt 3 ; then + echo "usage: $0 servername portno filelist" + exit 2 +fi + +HOSTNAME=$1 ; export HOSTNAME +PORTNO=$2 ; export PORTNO +FILELIST=$3 ; export FILELIST + +grep '^/' $FILELIST | cut -f1 | +( +while read URL +do + export URL + echo ">>>>> $URL" + ( + telnet $HOSTNAME $PORTNO << _EOF_ +GET $URL HTTP/1.0 + +_EOF_ + ) 2> /dev/null | head -5 | grep 'HTTP/1.0' + killall telnet +done +) diff --git a/apps/JAWS/clients/WebSTONE/bin/genfiles b/apps/JAWS/clients/WebSTONE/bin/genfiles new file mode 100755 index 00000000000..d5f06aee6df --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/genfiles @@ -0,0 +1,41 @@ +#! /bin/sh +# + +# get configuration +. $WEBSTONEROOT/conf/testbed + +cat $WEBSTONEROOT/conf/fileset | +nawk ' +($1 ~ /^[0-9][0-9]*[kK][bB]*$/) { + sub(/[kK][bB]*/, "", $1); + cmd = "$WEBSTONEROOT/bin/genrand " $1*1024 " " $2 + print cmd; + system(cmd); + next +} + +($1 ~ /^[0-9][0-9]*[mM][bB]*$/) { + sub(/[kK][bB]*/, "", $1); + cmd = "$WEBSTONEROOT/bin/genrand " $1*1024*1024 " " $2 + print cmd; + system(cmd); + next +} + +($1 ~ /^[0-9][0-9]*$/) { + sub(/[kK][bB]*/, "", $1); + cmd = "$WEBSTONEROOT/bin/genrand " $1 " " $2 + print cmd; + system(cmd); + next +} ' $* + +# copy files +files=`cat $WEBSTONEROOT/conf/fileset | cut -f2 -d' '` +for f in $files +do + $RCP $f $SERVER:$WEBDOCDIR + rm -f $f +done + +#end diff --git a/apps/JAWS/clients/WebSTONE/bin/genfiles-from-filelist.sh b/apps/JAWS/clients/WebSTONE/bin/genfiles-from-filelist.sh new file mode 100755 index 00000000000..1293709238c --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/genfiles-from-filelist.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# + +# get configuration +[ -n "$WEBSTONEROOT" ] || WEBSTONEROOT=`pwd`/.. +. $WEBSTONEROOT/conf/testbed + +case $# in + 1) + FILELIST=$1 + ;; + *) + FILELIST=$WEBSTONEROOT/conf/filelist + ;; +esac + +TIMESTAMP=`date +"%y%m%d_%H%M"` +mkdir $TMPDIR/webstone-genfiles.$TIMESTAMP +cd $TMPDIR/webstone-genfiles.$TIMESTAMP + +cat $FILELIST | +nawk ' +($3 ~ /^\#[0-9]*/) { + sub(/^\#/, "", $3); + cmd = WEBSTONEROOT "/bin/genrand " $3 " ."$1 + print cmd; + system(cmd); + cmd = RCP " ." $1 " " SERVER ":" WEBDOCDIR + print cmd; + system(cmd); + cmd = "rm -f ." $1 + print cmd; + system(cmd); + next +} +' $* WEBSTONEROOT=$WEBSTONEROOT RCP=$RCP SERVER=$SERVER WEBDOCDIR=$WEBDOCDIR + +cd $TMPDIR +rm -rf $TMPDIR/webstone-genfiles.$TIMESTAMP + +#end diff --git a/apps/JAWS/clients/WebSTONE/bin/gui-configure b/apps/JAWS/clients/WebSTONE/bin/gui-configure new file mode 100755 index 00000000000..dcea4e3fe1c --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/gui-configure @@ -0,0 +1,174 @@ +#!/bin/sh -- because we're not sure where perl is yet +# + +'true' || eval 'exec perl -S $0 $argv:q'; +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' +& eval 'exec /usr/local/bin/perl -S $0 $argv:q' + if 0; + +# Usage: [perl] configure [file] +# +# This replaces the program paths (e.g. /bin/awk) with an +# alternate path that is found in the file "file.paths". It also finds +# perl5 and changes the path in all the stand-alone perl programs. +# + +$debug = 0; + +# +# Target shell scripts in question: +@shell_scripts=("conf/paths.pl", "conf/paths.sh"); +@perl5_src = < bin/webstone-gui.pl bin/WebStone-common.pl bin/killbench.pl bin/view-results.pl bin/WebStone-manage.pl bin/move-filelist.pl bin/write-testbed.pl bin/WebStone-run.pl bin/move-runs.pl bin/WebStone-setup.pl bin/runbench.pl >; +@perl_src = < bin/wscollect.pl bin/mine-logs.pl >; +@benchmark_dir_src = < webstone bin/killbench bin/runbench >; + +# all the HTML browsers we know about, IN ORDER OF PREFERENCE! +@all_www= ("netscape", "Mosaic", "xmosaic", "lynx"); + +# +# Potential directories to find commands; first, find the user's path... +$PATH = $ENV{"PATH"}; + +# additional dirs; *COLON* separated! +$other_dirs="/usr/ccs/bin:/bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/ucb/bin:/usr/sbin:/usr/etc:/usr/local/bin:/usr/bin/X11:/usr/X11/bin:/usr/openwin/bin"; + +# +# split into a more reasonable format. Personal aliases come last. +@all_dirs = split(/:/, $other_dirs . ":" . $PATH); + +print "checking to make sure all the target(s) are here...\n"; + +for (@shell_scripts) { + die "ERROR -- $_ not found!\n" unless -f $_; + } + +# find perl +print "Trying to find perl...\n"; +for $dir (@all_dirs) { + # first, find where it might be + next if (! -d $dir); + while (<$dir/perl*>) { + if (-x $_) { + $perl_version=`($_ -v 2> /dev/null) | + awk '/This is perl/ { print $NF }'`; + if ($perl_version) { + $PERL=$_; + $pflag="1"; + last; + } + } + last if $pflag; + } + last if $pflag; + } + +if ($PERL) { + print "\nPerl is in $PERL\n"; + for (@perl_src) { $perl_src .= "$_ "; } + print "\nchanging the source in: $perl_src\n"; + system "$PERL -pi -e \"s@^#!.*/perl.*@#!$PERL@;\" $perl_src"; + + # make sure things are executable... + system("chmod u+x $perl_src"); +} +else +{ + printf "\nSome WebStone functions require Perl\n" unless $PERL; +} +# end if $PERL + +# find perl5 +$pflag = 0; +print "Trying to find perl5...\n"; +for $dir (@all_dirs) { + # first, find where it might be; oftentimes you'll see perl, + # perl4, perl5, etc. in the same dir + next if (! -d $dir); + while (<$dir/perl5* $dir/perl*>) { + if (-x $_) { + $perl_version=`($_ -v 2> /dev/null) | + awk '/This is perl, version 5/ { print $NF }'`; + if ($perl_version) { + $PERL5=$_; + $pflag="1"; + last; + } + } + last if $pflag; + } + last if $pflag; +} + +if ($PERL5) { + print "\nPerl5 is in $PERL5\n"; + + for (@perl5_src) { $perl5_src .= "$_ "; } + print "\nchanging the source in: $perl5_src\n"; + system "$PERL5 -pi -e \"s@^#!.*/perl.*@#!$PERL5@;\" $perl5_src"; + system("chmod u+x $perl5_src"); +} +else +{ + printf "\nThe WebStone GUI requires Perl5\n" unless $PERL5; +} +#end if $PERL5 + +# find the most preferred www viewer first. +for $www (@all_www) { + for $dir (@all_dirs) { + if (!$MOSAIC) { + if (-x "$dir/$www") { + $MOSAIC="$dir/$www"; + next; + } + } + } + } +if ($MOSAIC) { + print "\nHTML/WWW Browser is $MOSAIC\n"; + + $upper{"MOSAIC"} = $MOSAIC; + } +else { print "Cannot find a web browser! WebStone cannot be run except in CLI"; } + +print "\nOk, now doing substitutions on the shell scripts...\n"; +for $shell (@shell_scripts) { + print "Changing paths in $shell...\n"; + die "Can't open $shell\n" unless open(SCRIPT, $shell); + rename($shell, $shell . '.old'); + die "Can't open $shell\n" unless open(OUT, ">$shell"); + + # + # Open up the script, search for lines beginning with + # stuff like "TEST", "AWK", etc. If the file ends in "pl", + # assume it's a perl script and change it accordingly + while (<SCRIPT>) { + $found = 0; + for $command (keys %upper) { + if(/^\$?$command=/) { + # shell script + if ($shell !~ /.pl$/) { + print OUT "$command=$upper{$command}\n"; } + # perl script + else { + print OUT "\$" . "$command=\"$upper{$command}\";\n"; + } + $found = 1; + } + } + print OUT $_ if !$found; + + } + close(SCRIPT); + close(OUT); + } + + +for (@benchmark_dir_src) { $benchmark_dir_src .= "$_ "; } +print "\nchanging the source in: $benchmark_dir_src\n"; +$BENCHMARK_DIR=`pwd`; +chop $BENCHMARK_DIR; +$BENCHMARK_DIR =~ s/\//\\\//g; +system "$PERL -pi -e \"s/<BENCHMARK_DIR>/$BENCHMARK_DIR/\" $benchmark_dir_src"; + +# done... diff --git a/apps/JAWS/clients/WebSTONE/bin/killbench b/apps/JAWS/clients/WebSTONE/bin/killbench new file mode 100755 index 00000000000..2997d891dca --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/killbench @@ -0,0 +1,13 @@ +#!/bin/sh -x +# +# get configuration +. $WEBSTONEROOT/conf/testbed + +for i in $CLIENTS +do + $RSH -l root $i /etc/killall $1 webclient +done +# +sleep 1 +/etc/killall $1 webmaster +/etc/killall $1 runbench diff --git a/apps/JAWS/clients/WebSTONE/bin/killbench.pl b/apps/JAWS/clients/WebSTONE/bin/killbench.pl new file mode 100755 index 00000000000..42c616a79e0 --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/killbench.pl @@ -0,0 +1,15 @@ +#!/pkg/gnu/bin//perl5 +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +html_begin(); + +print CLIENT "<P>Killing WebStone processes<PRE>"; +system("$wd/bin/killbench"); +print CLIENT "</PRE><P>Done."; + +html_end(); + +# end diff --git a/apps/JAWS/clients/WebSTONE/bin/mine-logs.pl b/apps/JAWS/clients/WebSTONE/bin/mine-logs.pl new file mode 100755 index 00000000000..1b721aa46ae --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/mine-logs.pl @@ -0,0 +1,88 @@ +#!/pkg/gnu/bin//perl +# +# mine-logs.pl: +# script to transform access logs into WebStone workload +# +# created 18 December 1995 mblakele@engr.sgi.com +# +# functional map: +# usage: mine-logs.pl access.log +# +# 1. For each line in the input +# a. parse the URL and the time, the outcome code, and the size +# b. if the code is 200, and it's a GET, +# do we already know about this URL? +# i. yes - increment its counter +# ii. no - create a slot for it, record size, +# and set counter=1 +# + +$debug = 0; +$line_number = 0; + +while (<>) { + chomp; + + $line_number++; + ($line_number % 1000) || printf STDERR "."; + # parse line + ( $client, $junk1, $junk2, $date, $timezone, + $command, $url, $version, $result_code, $size ) = + split; + # strip some junk + $command =~ s/\"//; + $date =~ s/\[//; + + ($debug) && printf STDERR "$client, $date, $command, $url, $result_code, $size\n"; + + # is it a GET? Did it succeed? (i.e., is the result code 200?) + if (($command eq 'GET') && ($result_code == 200)) { + # is this URL already in the key set? + if (exists $counter{$url}) { + # URL is in key set + ($debug) && printf STDERR "URL $url already in key set: incrementing\n"; + $counter{$url}++; + if ($size == $size{$url}) { + ($debug) && printf STDERR "size mismatch on $url: $size != $size{$url}\n"; + if ($size <=> $size{$url}) { $size{$url} = $size; } + } + } + else { + # URL isn't in key set + ($debug) && printf STDERR "URL $url isn't in key set: adding size $size\n"; + $counter{$url} = 1; + $size{$url} = $size; + } + # end if key set + } # end if GET +} +# end of input file +printf STDERR "\n"; + +# now we print out a workload file + +# first, the headline +$date = `date`; +chomp($date); +printf "# WebStone workload file\n# \tgenerated by $0 $date\n#\n"; + +# next, sort the keys +@sorted_keys = sort by_counter keys(%counter); + +# iterate through sorted keys +foreach $key (@sorted_keys) { + # print url, weighting, and (commented) the size in bytes + ($debug) && printf STDERR "printing data for $key\n"; + printf "$key\t$counter{$key}\t#$size{$key}\n"; +} +# end foreach + +# end main + +sub +by_counter { + $counter{$b} <=> $counter{$a}; +} +# end by_counter + +# end mine-logs.pl diff --git a/apps/JAWS/clients/WebSTONE/bin/move-filelist.pl b/apps/JAWS/clients/WebSTONE/bin/move-filelist.pl new file mode 100755 index 00000000000..0155b83f972 --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/move-filelist.pl @@ -0,0 +1,26 @@ +#!/pkg/gnu/bin//perl5 +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +$oldfilelist = "$wd/conf/filelist"; + +html_begin(); + +if ($filelist ne $oldfilelist) { + $backup = $oldfilelist . ".bak"; + print CLIENT "<BODY>Backing up $oldfilelist to $backup"; + rename($oldfilelist, $backup); + print CLIENT "<P>Copying $filelist to $oldfilelist"; + link($filelist, $oldfilelist); + print CLIENT "<P>Done."; +} +else +{ + print CLIENT "<STRONG>Can't move $filelist <P>to $filelist</STRONG>"; +} + +html_end(); + +# end diff --git a/apps/JAWS/clients/WebSTONE/bin/move-runs.pl b/apps/JAWS/clients/WebSTONE/bin/move-runs.pl new file mode 100755 index 00000000000..a4ca528f034 --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/move-runs.pl @@ -0,0 +1,24 @@ +#!/pkg/gnu/bin//perl5 +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +html_begin(); + +if ($runsdir ne $oldrunsdir) { + print CLIENT "<BODY>Moving $oldrunsdir to $runsdir..."; + if (-e $runsdir) { + print CLIENT "<STRONG>Error: $runsdir already exists!</STRONG>"; + } + rename($oldrunsdir, $runsdir); + print CLIENT "<P>Done."; +} +else +{ + print CLIENT "<STRONG>Can't move $runsdir <P>to $oldrunsdir</STRONG>"; +} + +html_end(); + +# end diff --git a/apps/JAWS/clients/WebSTONE/bin/rebootall b/apps/JAWS/clients/WebSTONE/bin/rebootall new file mode 100755 index 00000000000..2de65110027 --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/rebootall @@ -0,0 +1,9 @@ +#! /bin/sh -x + +# get configuration +. $WEBSTONEROOT/conf/testbed + +for i in $CLIENTS +do + $RSH -l root $i "sleep 5 ; init 6" & +done diff --git a/apps/JAWS/clients/WebSTONE/bin/runbench b/apps/JAWS/clients/WebSTONE/bin/runbench new file mode 100755 index 00000000000..409351f8f55 --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/runbench @@ -0,0 +1,193 @@ +#!/bin/sh +# $Header$ +# set -x +set +x +[ -n "$WEBSTONEROOT" ] || WEBSTONEROOT=`pwd`/../ + +case $# in + 1) + FILELIST=$1 + ;; + *) + FILELIST=$WEBSTONEROOT/conf/filelist + ;; +esac + +# load configurations +. $WEBSTONEROOT/conf/testbed + +[ -n "$DEBUG" ] && set +x + +# check variables +[ -n "$ITERATIONS" ] || ITERATIONS="1" +[ -n "$MINCLIENTS" ] || MINCLIENTS="1" +[ -n "$MAXCLIENTS" ] || MAXCLIENTS="1" +[ -n "$CLIENTINCR" ] || CLIENTINCR="1" +[ -n "$TIMEPERRUN" ] || TIMEPERRUN="1" +# don't care about PROXYSERVER +[ -n "$SERVER" ] || SERVER="www" +[ -n "$PORTNO" ] || PORTNO="80" +# [ -n "$SERVERINFO" ] || SERVERINFO="uname -a" +# OSTUNINGFILES +# WEBSERVERDIR +# WEBDOCDIR +# WEBSERVERTUNINGFILES +[ -n "$CLIENTS" ] || CLIENTS="localhost" +[ -n "$CLIENTACCOUNT" ] || CLIENTACCOUNT=$USER +[ -n "$CLIENTPASSWORD" ] || CLIENTPASSWORD=$CLIENTACCOUNT +# [ -n "$CLIENTINFO" ] || CLIENTINFO="uname -a" +[ -n "$TMPDIR" ] || TMPDIR="/tmp" +[ -n "$RCP" ] || RCP="rcp" +[ -n "$RSH" ] || RSH="rsh" + +export ITERATIONS MINCLIENTS MAXCLIENTS CLIENTINCR TIMEPERRUN +export SERVER PORTNO SERVERINFO +export CLIENTS CLIENTACCOUNT CLIENTPASSWORD CLIENTINFO +export TMPDIR RCP RSH + +echo "Clients: " $CLIENTS + +# +# Estimate run time +# +NUMCLIENTHOSTS=`echo $CLIENTS | wc -w` +TRIALS=`expr 1 + \( $MAXCLIENTS - $MINCLIENTS \) / $CLIENTINCR` +RUNTIME=`expr 60 \* $ITERATIONS \* $TRIALS \* $TIMEPERRUN` +RUNTIME=`expr $RUNTIME + $TRIALS \* \( $MAXCLIENTS + $MINCLIENTS \) \ + / \( 2 \* $NUMCLIENTHOSTS \)` + +echo "Estimated run time:" `expr $RUNTIME / 3600` "hours" \ + `expr $RUNTIME % 3600 / 60` "minutes" + +# +# Checking for valid set of benchmark files to retrieve +# +#if [ -z "$PROXYSERVER" ] +#then +# echo "Checking for a valid set of benchmark files" +# CHECKLISTTMP=$TMPDIR/webstone-checkfilelist.$$ +# rm -f $CHECKFILELISTTMP +# $WEBSTONEROOT/bin/checkfilelist $SERVER $PORTNO $FILELIST > $CHECKLISTTMP 2>&1 +# if [ `grep -c ' 4[0-9][0-9] '< $CHECKLISTTMP` -gt 0 ] +# then +# echo "ERROR: not all files in filelist are on server:" +# echo "----- checkfilelist results -----" +# cat $CHECKLISTTMP +# echo "----- checkfilelist results -----" +# rm -f $CHECKLISTTMP +# exit 1 +# else +# echo "OK: All files found" +# fi +# rm -f $CHECKLISTTMP +#fi +# end if $PROXYSERVER + +# +# distribute webclient binary +# +for i in $CLIENTS +do + $RCP $WEBSTONEROOT/bin/webclient $i:$TMPDIR #/usr/local/bin +done + +# BEGIN iterations +J=1 +while [ $J -le $ITERATIONS ] +do + NUMCLIENTS=$MINCLIENTS + while [ $NUMCLIENTS -le $MAXCLIENTS ] + do + echo "***** Iteration $J, Total clients "`expr $NUMCLIENTS`" **********" + date + TIMESTAMP=`date +"%y%m%d_%H%M"` + LOGDIR=$WEBSTONEROOT/bin/runs/$TIMESTAMP + + # + # nuke debug files + # + for client in $CLIENTS + do + $RSH $client "rm /tmp/webstone-debug*" > /dev/null 2>&1 + done + + mkdir -p $LOGDIR + rm -f $LOGDIR/config + touch $LOGDIR/config + CLIENTSPERHOST=`expr $NUMCLIENTS / $NUMCLIENTHOSTS` + EXTRACLIENTS=`expr $NUMCLIENTS % $NUMCLIENTHOSTS` + + for i in $CLIENTS + do + if [ $EXTRACLIENTS -gt 0 ] + then + echo "$i $CLIENTACCOUNT $CLIENTPASSWORD `expr $CLIENTSPERHOST + 1`" \ + >> $LOGDIR/config + EXTRACLIENTS=`expr $EXTRACLIENTS - 1` + else + echo "$i $CLIENTACCOUNT $CLIENTPASSWORD $CLIENTSPERHOST" \ + >> $LOGDIR/config + fi + done + cp $FILELIST $LOGDIR/`basename $FILELIST` + + # + # Put test configuration files on clients + # + for i in $CLIENTS localhost + do + $RSH $i "rm -f $TMPDIR/config $TMPDIR/`basename $FILELIST`" + $RCP $LOGDIR/config $i:$TMPDIR/config + $RCP $LOGDIR/`basename $FILELIST` $i:$TMPDIR/filelist + done + + # + # Get starting configuration and stats from each participant + # + $RSH $SERVER "$SERVERINFO" > $LOGDIR/hardware.$SERVER 2>&1 + for i in $CLIENTS + do + $RSH $i "$CLIENTINFO" > $LOGDIR/hardware.$i 2>&1 + done + + # set -x + for i in $OSTUNINGFILES $WEBSERVERTUNINGFILES + do + $RCP $SERVER:$i $LOGDIR + done + set +x + + # + # Run benchmark + # + date + CMD="$WEBSTONEROOT/bin/webmaster -v -u $TMPDIR/filelist" + CMD=$CMD" -f $TMPDIR/config -l $TIMEPERRUN" + [ -n "$SERVER" ] && CMD=$CMD" -w $SERVER" + [ -n "$PORTNO" ] && CMD=$CMD" -p $PORTNO" + [ -n "$PROXYSERVER" ] && CMD=$CMD" -P $PROXYSERVER" + [ -n "$DEBUG" ] && CMD=$CMD" -d" + echo $CMD + + # dump environment into $LOGDIR + rm -rf $LOGDIR/controller.env + env > $LOGDIR/controller.env + + $CMD | tee $LOGDIR/run + + # + # Get ending configuration and stats from each participant + # + date + #for i in $SERVER $CLIENTS + #do + #$WEBSTONEROOT/bin/getstats $i > $LOGDIR/end.$i 2>&1 + #done + #date + NUMCLIENTS=`expr $NUMCLIENTS + $CLIENTINCR` + done + # while NUMCLIENTS + J=`expr $J + 1` +done +# while J +# end diff --git a/apps/JAWS/clients/WebSTONE/bin/runbench.pl b/apps/JAWS/clients/WebSTONE/bin/runbench.pl new file mode 100755 index 00000000000..81071504f1a --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/runbench.pl @@ -0,0 +1,36 @@ +#!/pkg/gnu/bin//perl5 +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); +require('flush.pl'); + +# force flush after every write or print +$| = 1; + +html_begin("In Progress"); + +print CLIENT "<H3><CENTER>Running WebStone</CENTER></H3><PRE>"; +show_model(); +&flush(CLIENT); +&flush(STDOUT); + +&start_runbench(); + +print CLIENT <<EOF +<TITLE>WebStone Completed</TITLE> +</PRE><CENTER> +<FORM METHOD=POST ACTION="http://localhost:$html_port$wd/bin/view-results.pl"> +<INPUT TYPE="submit" VALUE="View Results"> +</CENTER> +EOF + ; + +html_end(); + +sub start_runbench { + $command = "cd $wd/bin; ./runbench"; + system($command); +} + +# end diff --git a/apps/JAWS/clients/WebSTONE/bin/tabs2html b/apps/JAWS/clients/WebSTONE/bin/tabs2html new file mode 100755 index 00000000000..8c7d851c357 --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/tabs2html @@ -0,0 +1,13 @@ +#! /bin/sh + +nawk ' +BEGIN { FS=" " ; print "<BODY><TABLE>" } +{ + print "<TR ALIGN=RIGHT VALIGN=BOTTOM>" + for (i=1; i <= NF; i++) { + print "<TD>" $i "</TD>" + } + print "</TR>" +} +END { print "</TABLE></BODY>" } +' $* diff --git a/apps/JAWS/clients/WebSTONE/bin/view-results.pl b/apps/JAWS/clients/WebSTONE/bin/view-results.pl new file mode 100755 index 00000000000..7ff961efcca --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/view-results.pl @@ -0,0 +1,53 @@ +#!/pkg/gnu/bin//perl5 +# +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +require('wscollect.pl'); + +$debug = 0; + +$printedTitles = 0; + +html_begin("Results"); + +print CLIENT "<H3>WebStone Results</H3>"; + +($debug) && print STDERR "opening table\n"; +print CLIENT "<BODY><TABLE BORDER=1>\r"; + +@directories = ("$wd/bin/runs"); +directory: for (@directories) { + &find($_); +} + +($debug) && print STDERR "closing table\n"; +print CLIENT "</TABLE></BODY>\r"; + +html_end(); + +# end main + +sub printcustom { + if (!$printedTitles) { + $printedTitles = 1; + print CLIENT "<TR>"; + for $title (@title) { + print CLIENT "<TH>$title</TH>\r"; + } # end for title + print CLIENT "</TR>\r"; + } + print CLIENT "<TR>"; + $first_column = 1; + for $data (@data) { + if ($first_column) { + $first_column = 0; + print CLIENT "<TD><A HREF=$wd/bin/runs/$data>$data</A></TD>\r"; + } else { + print CLIENT "<TD ALIGN=RIGHT>$data</TD>\r"; + } + } # end for data + print CLIENT "</TR>\r"; +} + +# end diff --git a/apps/JAWS/clients/WebSTONE/bin/webstone-gui.pl b/apps/JAWS/clients/WebSTONE/bin/webstone-gui.pl new file mode 100755 index 00000000000..006cd9eba7c --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/webstone-gui.pl @@ -0,0 +1,316 @@ +#!/pkg/gnu/bin//perl5 + +require 'conf/paths.pl'; + +#$debug = 1; +$HELPME="http://reality.sgi.com/employees/mblakele_engr/WebStone/"; +$| = 1; # set pipes to hot + +&html(); + +sub html { + local($helper, $wd); + + &start_html_server(); + # These strings are used in, among others, PERL-to-HTML scripts. + # + $wd = `pwd`; + chop $wd; + + print "$html_port\n" if $debug; + + $HTML_STARTPAGE = "http://localhost:$html_port$wd/doc/WebStone.html"; + + # + # Fork off the HTML client, and fork off a server process that + # handles requests from that client. The parent process waits + # until the client exits and terminates the server. + # + print "Starting $MOSAIC...\n" if $debug; + + if (($client = fork()) == 0) { + foreach (keys %ENV) { + delete $ENV{$_} if (/proxy/i && !/no_proxy/i); + } + exec($MOSAIC, "$HTML_STARTPAGE") + || die "cannot exec $MOSAIC: $!"; + } + + if (($server = fork()) == 0) { + if (($helper = fork()) == 0) { + alarm 3600; + &patience(); + } + kill 'TERM',$helper; + $SIG{'PIPE'} = 'IGNORE'; + for (;;) { + accept(CLIENT, SOCK) || die "accept: $!"; + select((select(CLIENT), $| = 1)[0]); + &process_html_request(); + close(CLIENT); + } + } + + # + # Wait until the client terminates, then terminate the server. + # + close(SOCK); + waitpid($client, 0); + kill('TERM', $server); + exit; +} + +# +# Set up a listener on an arbitrary port. There is no good reason to +# listen on a well-known port number. +# +sub start_html_server { + local($sockaddr, $proto, $junk); + + $AF_INET = 2; + $SOCK_STREAM = 2; + $PORT = 0; #1024; + + $sockaddr = 'S n a4 x8'; + $this = pack($sockaddr, $AF_INET, $PORT, "\0\0\0\0"); + ($junk, $junk, $proto) = getprotobyname('tcp'); + socket(SOCK, $AF_INET, $SOCK_STREAM, $proto) || die "socket: $!"; + setsockopt(SOCK, 0xffff, 0x0004, 1) || die "setsockopt: $!"; + bind(SOCK, $this) || die "bind: $!"; + listen(SOCK, 1) || die "listen: $!"; + ($junk, $html_port) = unpack($sockaddr, getsockname(SOCK)); +} + + +# +# Process one client request. We expect the client to send stuff that +# begins with: +# +# command /password/perl_script junk +# +# Where perl_script is the name of a perl file that is executed via +# do "perl_script"; +# +# In case of a POST command the values in the client's attribute-value +# list are assigned to the corresponding global PERL variables. +# +sub process_html_request { + local($request, $command, $script, $magic, $url, $peer); + local(%args); + + # + # Parse the command and URL. Update the default file prefix. + # + $request = <CLIENT>; + print $request if $debug; + ($command, $url) = split(/\s+/, $request); + if ($command eq "" || $command eq "QUIT") { + return; + } + + #($junk, $script) = split(/\//, $url, 2); + #($script, $html_script_args) = split(',', $script, 2); + #($HTML_CWD = "file:$script") =~ s/\/[^\/]*$//; + $script = $url; + + while (<CLIENT>) { + last if (/^\s+$/); + } + + if ($command eq "GET") { + if (-d $script) { + get_dir($script); + } + elsif ($script =~ /\.pl\b/) { + perl_html_script($script); + } + else { + get_file($script); + } + } elsif ($command eq "POST") { + + print $request if $debug; + flush; + # + # Process the attribute-value list. + # + if ($_ = <CLIENT>) { + print "Hi $_" if $debug; + flush; + s/\s+$//; + s/^/\n/; + s/&/\n/g; + $html_post_attributes = ''; + $* = 1; + for (split(/(%[0-9][0-9A-Z])/, $_)) { + $html_post_attributes .= (/%([0-9][0-9A-Z])/) ? + pack('c',hex($1)) : $_; + } + %args = ('_junk_', split(/\n([^=]+)=/, $html_post_attributes)); + delete $args{'_junk_'}; + for (keys %args) { + print "\$$_ = $args{$_}\n" if $debug; + ${$_} = $args{$_}; + } + perl_html_script($script); + } else { + &bad_html_form($script); + } + } else { + &bad_html_command($request); + } +} + + +# +# Unexpected HTML command. +# +sub bad_html_command { + local($request) = @_; + + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>Unknown command</TITLE> +<LINK REV="made" HREF=$HELPME> +</HEAD> +<BODY> +<H1>Unknown command</H1> +The command <TT>$request<TT> was not recognized. +</BODY> +</HTML> +EOF +; +} + +# +# Execute PERL script +# +sub perl_html_script { + local($script) = @_; + + if (! -e $script) { + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>File not found</TITLE> +<LINK REV="made" HREF=$HELPME> +</HEAD> +<BODY> +<H1>File not found</H1> +The file <TT>$script</TT> does not exist or is not accessible. +</BODY> +</HTML> +EOF +; return; + } + do $script; + if ($@ && ($@ ne "\n")) { + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>Command failed</TITLE> +<LINK REV="made" HREF=$HELPME> +</HEAD> +<BODY> +<H1>Command failed</H1> +$@ +</BODY> +</HTML> +EOF +; + } +} + +# +# Missing attribute list +# +sub bad_html_form { + local($script) = @_; + + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>No attribute list</TITLE> +<LINK REV="made" HREF=$HELPME> +</HEAD> +<BODY> +<H1>No attribute list</H1> + +No attribute list was found. +</BODY> +</HTML> +EOF +; +} + +# +# Give them something to read while the server is initializing. +# +sub patience { + for (;;) { + accept(CLIENT, SOCK) || die "accept: $!"; + <CLIENT>; + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>Initializing...</TITLE> +<LINK REV="made" HREF=$HELPME> +</HEAD> +<BODY> +<H1>Initializing...</H1> +WebStone is initializing... +</BODY> +</HTML> +EOF +; + close(CLIENT); + } +} + +sub get_file { + local($file) = @_; + + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>$file</TITLE> +</HEAD> +<H1>$file</H1> +<BODY><PRE> +EOF + unless ($file =~ /(html|htm|gif|jpeg|jpg)\b/); + + open(FILE, $file); + while (<FILE>) { + print CLIENT $_; + } + close(FILE); + + print CLIENT <<EOF +</PRE> +</HTML> +EOF + unless ($file =~ /(html|htm|gif|jpeg|jpg)\b/); +} + +sub get_dir { + local($dir) = @_; + opendir(DIRECTORY, $dir); + @listing = readdir(DIRECTORY); + closedir(DIRECTORY); + print CLIENT <<EOF +<HTML> +<HEAD> +<TITLE>$dir</TITLE> +</HEAD> +<H1>$dir</H1> +<BODY> +EOF + ; + + while (<@listing>) { + print CLIENT "<P><A HREF=$dir/$_>$_</A>"; + } + print CLIENT "</HTML>"; +} diff --git a/apps/JAWS/clients/WebSTONE/bin/write-testbed.pl b/apps/JAWS/clients/WebSTONE/bin/write-testbed.pl new file mode 100755 index 00000000000..9f2c75af0ba --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/write-testbed.pl @@ -0,0 +1,47 @@ +#!/pkg/gnu/bin//perl5 +# +# write new values from form to $wd/conf/testbed, and run WebStone +# + +push(@INC, "$wd/bin"); +require('WebStone-common.pl'); + +html_begin("Current Configuration"); + +&show_model(); +&write_data(); + +print CLIENT <<EOF +<HR> +<FORM METHOD="POST" ACTION="$wd/bin/runbench.pl"> +<P><INPUT TYPE="SUBMIT" VALUE="Run WebStone"> +</FORM> +</DL> + +EOF + ; + +html_end(); + +# end main + +sub write_data { + rename("$wd/conf/testbed", "$wd/conf/testbed.bak") || + die "rename testbed: $!\n"; + open(TESTBED, ">>$wd/conf/testbed") || die "open testbed: $!\n"; + + print CLIENT "<PRE>"; + + foreach $key (@keylist) { + $$key =~ s/\+/ /g; + $newvalue = "$key=\"$$key\"\n"; + print CLIENT $newvalue; + print TESTBED $newvalue; + } + + print CLIENT "</PRE>"; + + close(TESTBED); +} + +# end diff --git a/apps/JAWS/clients/WebSTONE/bin/wscollect.pl b/apps/JAWS/clients/WebSTONE/bin/wscollect.pl new file mode 100755 index 00000000000..adf5fee56eb --- /dev/null +++ b/apps/JAWS/clients/WebSTONE/bin/wscollect.pl @@ -0,0 +1,139 @@ +#!/pkg/gnu/bin//perl +# $Header$ +# updated version of the old wscollect script which goes through +# webstone run directories and summarizes the output in tabular +# format. +# syc 4/25/96 +# + +require "find.pl"; + +# +# the list @runs contains the timestamps for the runs which are found +# during the traversal of the runs directory. This list is used for +# indices into the associative arrays for storing run information. +# +# $numclients{ $time } - number of clients for the run +# $connrate{ $time } - connection rate average +# $littlesload{ $time } - little's load factor +# $latency{ $time } - latency average +# $error{ $time } - error rate +# $throughput{ $time } - throughput + +local( @runs, + %numclients, + %connrate, + %littlesload, + %latency, + %error, + %throughput); + +# Got rid of the trick hack of the title names, someone can put it +# back in later +@title = ( "Timestamp", + "Total number of clients", + "Connection rate average (conn/s)", + "Little's Load Factor", + "Average Latency (seconds)", + "Error Level (%)", + "Throughput avg. for all connections (MBits/s)"); + + +push( @ARGV, ".") if ( !@ARGV ); + +for (@ARGV) { + &find( $_ ); +} + +&PrintOutput; + +1; + +sub wanted { + local( $filename ) = $_; + + return unless ( $filename =~ /run/ ); + + local( $instats) = 0; + local( $runtime, $tag, $data, $cruft, @cruft ); + + open( FILE, $filename ) || return; # bail if failed to open + $runtime = `pwd`; + @cruft = split(/\//,$runtime); + $runtime = pop( @cruft); + chop( $runtime); + push( @runs, $runtime); + while ( $line = <FILE>) { + if (! $instats) { + $instats = 1 if ( $line =~ /^WEBSTONE 2\.0 results/ ); + next; + } + chop( $line ); + ( $tag, $data ) = split( /:?\s{2,}|\t/, $line); + + # perl hack to emulate case/switch statement + $tag =~ /number of clients/ && + ($numclients{ $runtime } = $data, next); + $tag =~ /error rate/ && + (( $error{ $runtime }) = $data =~ /([\d\.]+)/, next); + $tag =~ /connection rate/ && + (( $connrate{ $runtime }) = $data =~ /([\d\.]+)/, next); + $tag =~ /Server thruput/ && + (( $throughput{ $runtime }) = $data =~ /([\d\.]+)/, next); + $tag =~ /Little's Load/ && + (( $littlesload{ $runtime}) = $data =~ /([\d\.]+)/, next); # ' + $tag =~ /Average response time/ && + (( $latency{ $runtime } ) = $data =~ /([\d\.]+)/, next); + } + close( FILE ); + unless ( $throughput{ $runtime} ) { + pop( @runs); # if we didn't get a throughput, then the + # data is incomplete and just drop this run + } +} + + +sub printdata { + local ($timestamp, $num_clients, $conn_rate, + $load, $latency, $error, $tput) = @_; + format STDOUT = +@<<<<<<<<<<< @###### @######.## @####.## @###.#### @####.#### @######.## +$timestamp, $num_clients, $conn_rate, $load, $latency, $error, $tput +. + + if (!$printedTitles) { + $printedTitles = 1; + ($ttimestamp, $tnum_clients, $tconn_rate, + $tload, $tlatency, $terror, $ttput) = @title; + format STDOUT_TOP = +^||||||||||| ^||||||| ^||||||||| ^||||||| ^||||||||| ^||||||||| ^||||||||||| +$ttimestamp, $tnum_clients, $tconn_rate, $tload, $tlatency, $terror, $ttput +^||||||||||| ^||||||| ^||||||||| ^||||||| ^||||||||| ^||||||||| ^||||||||||| +$ttimestamp, $tnum_clients, $tconn_rate, $tload, $tlatency, $terror, $ttput +^||||||||||| ^||||||| ^||||||||| ^||||||| ^||||||||| ^||||||||| ^||||||||||| +$ttimestamp, $tnum_clients, $tconn_rate, $tload, $tlatency, $terror, $ttput +^||||||||||| ^||||||| ^||||||||| ^||||||| ^||||||||| ^||||||||| ^||||||||||| +$ttimestamp, $tnum_clients, $tconn_rate, $tload, $tlatency, $terror, $ttput +^||||||||||| ^||||||| ^||||||||| ^||||||| ^||||||||| ^||||||||| ^||||||||||| +$ttimestamp, $tnum_clients, $tconn_rate, $tload, $tlatency, $terror, $ttput +---------------------------------------------------------------------------- +. + # write STDOUT_TOP; + } # end if printedTitles + write STDOUT; +} + +sub PrintOutput { + local( $runtime ); + + for $runtime (sort @runs) { + &printdata( $runtime, $numclients{ $runtime}, $connrate{ $runtime}, + $littlesload{ $runtime}, $latency{ $runtime}, $error{ $runtime}, + $throughput{ $runtime}); + } +} + + + + + |