001: // ServerStress.java
002: // $Id: ServerStress.java,v 1.3 2000/08/16 21:37:48 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1996.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.jigsaw.tests;
007:
008: import java.net.URL;
009: import java.net.URLConnection;
010:
011: import java.io.BufferedInputStream;
012: import java.io.DataInputStream;
013: import java.io.FileInputStream;
014: import java.io.FilterInputStream;
015: import java.io.InputStream;
016: import java.io.PrintStream;
017:
018: import java.util.Vector;
019:
020: import org.w3c.tools.timers.EventHandler;
021: import org.w3c.tools.timers.EventManager;
022:
023: class URLStat {
024: URL url = null;
025: long time = 0;
026: int count = 0;
027: int size = 0;
028: int failed = 0;
029:
030: public synchronized void update(int size, long time) {
031: if ((this .size == 0) && (size > 0)) {
032: this .size = size;
033: this .time = time;
034: } else if (this .size != size) {
035: failed++;
036: } else {
037: this .time += time;
038: this .count++;
039: }
040: }
041:
042: public synchronized void display(PrintStream out) {
043: out.println(url.toExternalForm() + ": s=" + size + " t="
044: + (((double) time / 1000.0) / ((double) count)) + " f="
045: + failed + " t=" + time + " c=" + count);
046: }
047:
048: public URL getURL() {
049: return url;
050: }
051:
052: URLStat(URL url) {
053: this .url = url;
054: this .time = 0;
055: this .count = 0;
056: }
057:
058: }
059:
060: class URLGetter extends Thread {
061: Stresser s = null;
062:
063: /**
064: * Keep picking an URL until the stresser tells us to stop.
065: * Each time a full URL has been fetched, notify the stresser, and try
066: * continuing.
067: */
068:
069: public void run() {
070: URLStat u = null;
071:
072: try {
073: while ((u = s.pickURL()) != null) {
074: int got = 0;
075: int size = 0;
076: byte buffer[] = new byte[8192];
077:
078: long tstart = System.currentTimeMillis();
079: try {
080: URLConnection conn = u.getURL().openConnection();
081: InputStream in = conn.getInputStream();
082: while ((got = in.read(buffer)) > 0)
083: size += got;
084: in.close();
085: } catch (Exception ex) {
086: size = -1;
087: }
088: s.notifyDone(u, size, System.currentTimeMillis()
089: - tstart);
090: }
091: } catch (Exception ex) {
092: }
093: s.notifyEnd(this );
094: }
095:
096: URLGetter(Stresser s) {
097: this .s = s;
098: }
099: }
100:
101: class Stresser extends Thread implements EventHandler {
102: private final boolean debug = false;
103: long duration = -1;
104: int parallel = 10;
105: Vector stats = null;
106: URLGetter getters[] = null;
107: boolean done = false;
108:
109: EventManager manager = null;
110:
111: /**
112: * Statistics
113: */
114: public long total_request = 0;
115: public long total_time = 0;
116:
117: public synchronized void handleTimerEvent(Object data, long time) {
118: if (debug)
119: System.out.println("shuting down...");
120: done = true;
121: }
122:
123: public synchronized void notifyDone(URLStat u, int size, long time) {
124: u.update(size, time);
125: total_request++;
126: }
127:
128: public synchronized void notifyEnd(URLGetter getter) {
129: parallel--;
130: notifyAll();
131: }
132:
133: public int url_counter = 0;
134:
135: public synchronized URLStat pickURL() {
136: if (done)
137: return null;
138: url_counter = (url_counter + 1) % stats.size();
139: return (URLStat) stats.elementAt(url_counter);
140: }
141:
142: public synchronized void waitForCompletion() {
143: while (parallel != 0) {
144: try {
145: wait();
146: } catch (InterruptedException ex) {
147: }
148: if (debug)
149: System.out.println("waiting for " + parallel
150: + " getters.");
151: }
152: }
153:
154: /**
155: * Start all URL getters, until the duration has expired.
156: */
157:
158: public void run() {
159: long tstart = System.currentTimeMillis();
160: // Start all getters:
161: for (int i = 0; i < parallel; i++)
162: getters[i].start();
163: // Wait for termination:
164: waitForCompletion();
165: // Display results:
166: long tend = System.currentTimeMillis();
167: System.out.println("Total request: " + total_request);
168: System.out.println("Total time : " + (tend - tstart));
169: System.out
170: .println("Req/sec : "
171: + (((double) total_request) / ((double) (tend - tstart)))
172: * 1000);
173: System.out.println("detailed results:");
174: for (int i = 0; i < stats.size(); i++) {
175: ((URLStat) stats.elementAt(i)).display(System.out);
176: }
177: }
178:
179: Stresser(Vector urls, long duration, int parallel) {
180: // Initialize instance vars:
181: this .duration = duration;
182: this .parallel = parallel;
183: // Create the getters:
184: this .getters = new URLGetter[parallel];
185: for (int i = 0; i < parallel; i++)
186: getters[i] = new URLGetter(this );
187: // Create the url stat objects:
188: this .stats = new Vector(urls.size());
189: for (int i = 0; i < urls.size(); i++)
190: stats.addElement(new URLStat((URL) urls.elementAt(i)));
191: // Create an event manager, and register for event at end of duration
192: this .manager = new EventManager();
193: this .manager.setDaemon(true);
194: this .manager.start();
195: this .manager.registerTimer(duration, this , null);
196: }
197:
198: }
199:
200: /**
201: * Stress a web server for a given duration of time.
202: * This program will run a constant rate of requests to a given server,
203: * for a given duration of time.
204: * <p><b>This test results should be taken with care</b>: they depend on a
205: * number of things, and usually run slower then C-written tests. They are
206: * included in Jigsaw release for testing only (not for real benchmarking,
207: * altough you are free to doi whatever you want with the numbers you get).
208: */
209:
210: public class ServerStress {
211:
212: public static void usage() {
213: PrintStream o = System.out;
214: o.println("usage: ServerStress <options>");
215: o.println("-d duration: duration of test in ms.");
216: o.println("-p parallel: number of parallel requests to run.");
217: o.println("-u url : add URL to list of url to visit.");
218: o.println("-f file : add all URL in file (one per line)");
219: System.exit(1);
220: }
221:
222: public static void main(String args[]) {
223: Vector urls = new Vector(); // List of urls to visit
224: long duration = 60000; // Duration in ms.
225: int par = 10; // # of parallel reqs to run
226: String filename = null;
227:
228: // Parse the command line:
229: for (int i = 0; i < args.length; i++) {
230: if (args[i].equals("-d") && (i + 1 < args.length)) {
231: try {
232: duration = Integer.parseInt(args[++i]);
233: } catch (Exception ex) {
234: usage();
235: }
236: } else if (args[i].equals("-u") && (i + 1 < args.length)) {
237: try {
238: urls.addElement(new URL(args[++i]));
239: } catch (Exception ex) {
240: usage();
241: }
242: } else if (args[i].equals("-p") && (i + 1 < args.length)) {
243: try {
244: par = Integer.parseInt(args[++i]);
245: } catch (Exception ex) {
246: usage();
247: }
248: } else if (args[i].equals("-f") && (i + 1 < args.length)) {
249: filename = args[++i];
250: } else {
251: usage();
252: }
253: }
254: // Update URL list with file if needed:
255: if (filename != null) {
256: try {
257: String line = null;
258: DataInputStream in = (new DataInputStream(
259: new BufferedInputStream(new FileInputStream(
260: filename))));
261: while ((line = in.readLine()) != null)
262: urls.addElement(new URL(line));
263: in.close();
264: } catch (Exception ex) {
265: System.out.println("Unable to read URL file "
266: + filename);
267: ex.printStackTrace();
268: System.exit(1);
269: }
270: }
271: // Build the stresser:
272: Stresser s = new Stresser(urls, duration, par);
273: s.start();
274: }
275:
276: }
|