// ServerStress.java
// $Id: ServerStress.java,v 1.3 2000/08/16 21:37:48 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.jigsaw.tests ;
import java.net.URL;
import java.net.URLConnection;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FilterInputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Vector;
import org.w3c.tools.timers.EventHandler;
import org.w3c.tools.timers.EventManager;
class URLStat {
URL url = null ;
long time = 0 ;
int count = 0 ;
int size = 0 ;
int failed = 0 ;
public synchronized void update(int size, long time) {
if ((this.size == 0) && (size > 0)) {
this.size = size ;
this.time = time ;
} else if ( this.size != size ) {
failed++ ;
} else {
this.time += time ;
this.count++ ;
}
}
public synchronized void display(PrintStream out) {
out.println(url.toExternalForm()
+ ": s=" + size
+ " t=" + (((double) time/1000.0) / ((double) count))
+ " f=" + failed
+ " t=" + time
+ " c=" + count) ;
}
public URL getURL() {
return url;
}
URLStat(URL url) {
this.url = url ;
this.time = 0 ;
this.count = 0 ;
}
}
class URLGetter extends Thread {
Stresser s = null ;
/**
* Keep picking an URL until the stresser tells us to stop.
* Each time a full URL has been fetched, notify the stresser, and try
* continuing.
*/
public void run() {
URLStat u = null ;
try {
while ((u = s.pickURL()) != null) {
int got = 0 ;
int size = 0 ;
byte buffer[] = new byte[8192] ;
long tstart = System.currentTimeMillis() ;
try {
URLConnection conn = u.getURL().openConnection() ;
InputStream in = conn.getInputStream() ;
while ((got = in.read(buffer)) > 0)
size += got ;
in.close() ;
} catch (Exception ex) {
size = -1 ;
}
s.notifyDone(u, size, System.currentTimeMillis() - tstart) ;
}
} catch (Exception ex) {
}
s.notifyEnd(this) ;
}
URLGetter(Stresser s) {
this.s = s ;
}
}
class Stresser extends Thread implements EventHandler {
private final boolean debug = false ;
long duration = -1 ;
int parallel = 10 ;
Vector stats = null ;
URLGetter getters[] = null ;
boolean done = false ;
EventManager manager = null ;
/**
* Statistics
*/
public long total_request = 0 ;
public long total_time = 0 ;
public synchronized void handleTimerEvent(Object data, long time) {
if ( debug )
System.out.println("shuting down...") ;
done = true ;
}
public synchronized void notifyDone(URLStat u, int size, long time) {
u.update(size, time) ;
total_request++ ;
}
public synchronized void notifyEnd(URLGetter getter) {
parallel-- ;
notifyAll() ;
}
public int url_counter = 0 ;
public synchronized URLStat pickURL() {
if ( done )
return null ;
url_counter = (url_counter + 1) % stats.size() ;
return (URLStat) stats.elementAt(url_counter) ;
}
public synchronized void waitForCompletion() {
while ( parallel != 0 ) {
try {
wait() ;
} catch (InterruptedException ex) {
}
if ( debug )
System.out.println("waiting for "+parallel+" getters.");
}
}
/**
* Start all URL getters, until the duration has expired.
*/
public void run() {
long tstart = System.currentTimeMillis() ;
// Start all getters:
for (int i = 0 ; i < parallel ; i++)
getters[i].start() ;
// Wait for termination:
waitForCompletion() ;
// Display results:
long tend = System.currentTimeMillis() ;
System.out.println("Total request: "+total_request) ;
System.out.println("Total time : "+(tend-tstart)) ;
System.out.println("Req/sec : "
+(((double)total_request)/((double)(tend-tstart)))*1000);
System.out.println("detailed results:") ;
for (int i = 0 ; i < stats.size() ; i++) {
((URLStat) stats.elementAt(i)).display(System.out) ;
}
}
Stresser(Vector urls, long duration, int parallel) {
// Initialize instance vars:
this.duration = duration ;
this.parallel = parallel ;
// Create the getters:
this.getters = new URLGetter[parallel] ;
for (int i = 0 ; i < parallel ; i++)
getters[i] = new URLGetter(this) ;
// Create the url stat objects:
this.stats = new Vector(urls.size()) ;
for (int i = 0 ; i < urls.size() ; i++)
stats.addElement(new URLStat((URL) urls.elementAt(i))) ;
// Create an event manager, and register for event at end of duration
this.manager = new EventManager();
this.manager.setDaemon(true) ;
this.manager.start() ;
this.manager.registerTimer(duration, this, null) ;
}
}
/**
* Stress a web server for a given duration of time.
* This program will run a constant rate of requests to a given server,
* for a given duration of time.
* <p><b>This test results should be taken with care</b>: they depend on a
* number of things, and usually run slower then C-written tests. They are
* included in Jigsaw release for testing only (not for real benchmarking,
* altough you are free to doi whatever you want with the numbers you get).
*/
public class ServerStress {
public static void usage() {
PrintStream o = System.out ;
o.println("usage: ServerStress <options>") ;
o.println("-d duration: duration of test in ms.") ;
o.println("-p parallel: number of parallel requests to run.") ;
o.println("-u url : add URL to list of url to visit.");
o.println("-f file : add all URL in file (one per line)") ;
System.exit(1) ;
}
public static void main (String args[]) {
Vector urls = new Vector() ; // List of urls to visit
long duration = 60000 ; // Duration in ms.
int par = 10 ; // # of parallel reqs to run
String filename = null ;
// Parse the command line:
for (int i = 0 ; i < args.length ; i++) {
if (args[i].equals("-d") && (i+1 < args.length)) {
try {
duration = Integer.parseInt(args[++i]) ;
} catch (Exception ex) {
usage() ;
}
} else if (args[i].equals("-u") && (i+1 < args.length)) {
try {
urls.addElement(new URL(args[++i])) ;
} catch (Exception ex) {
usage() ;
}
} else if (args[i].equals("-p") && (i+1 < args.length)) {
try {
par = Integer.parseInt(args[++i]) ;
} catch (Exception ex) {
usage() ;
}
} else if (args[i].equals("-f") && (i+1 < args.length)) {
filename = args[++i] ;
} else {
usage() ;
}
}
// Update URL list with file if needed:
if ( filename != null ) {
try {
String line = null ;
DataInputStream in = (new DataInputStream
(new BufferedInputStream
(new FileInputStream(filename)))) ;
while ((line = in.readLine()) != null)
urls.addElement(new URL(line)) ;
in.close() ;
} catch (Exception ex) {
System.out.println("Unable to read URL file "+filename) ;
ex.printStackTrace() ;
System.exit(1) ;
}
}
// Build the stresser:
Stresser s = new Stresser(urls, duration, par) ;
s.start() ;
}
}