001: /*
002: * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: */
007: package winstone.testCase.load;
008:
009: import java.io.IOException;
010: import java.io.InputStream;
011:
012: import org.xml.sax.SAXException;
013:
014: import winstone.Logger;
015: import winstone.WinstoneResourceBundle;
016:
017: import com.meterware.httpunit.GetMethodWebRequest;
018: import com.meterware.httpunit.WebConversation;
019: import com.meterware.httpunit.WebRequest;
020: import com.meterware.httpunit.WebResponse;
021:
022: /**
023: * A single worked thread in the load testing program
024: *
025: * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
026: * @version $Id: LoadTestThread.java,v 1.2 2006/02/28 07:32:49 rickknowles Exp $
027: */
028: public class LoadTestThread implements Runnable {
029: private WinstoneResourceBundle resources;
030: private String url;
031: private long delayBeforeStarting;
032: private LoadTest loadTest;
033: private WebConversation webConv;
034: private Thread thread;
035: private boolean interrupted;
036: private LoadTestThread next;
037:
038: public LoadTestThread(String url, LoadTest loadTest,
039: WinstoneResourceBundle resources, WebConversation webConv,
040: int delayedThreads) {
041: this .resources = resources;
042: this .url = url;
043: this .loadTest = loadTest;
044: this .webConv = webConv;
045: this .delayBeforeStarting = 1000 * delayedThreads;
046: this .interrupted = false;
047: this .thread = new Thread(this );
048: this .thread.setDaemon(true);
049: this .thread.start();
050:
051: // Launch the next second's getter
052: if (delayedThreads > 0)
053: this .next = new LoadTestThread(url, loadTest, resources,
054: webConv, delayedThreads - 1);
055: }
056:
057: public void run() {
058: if (this .delayBeforeStarting > 0)
059: try {
060: Thread.sleep(this .delayBeforeStarting);
061: } catch (InterruptedException err) {
062: }
063:
064: long startTime = System.currentTimeMillis();
065:
066: try {
067: if (this .webConv == null)
068: this .webConv = new WebConversation();
069:
070: // Access the URL
071: WebRequest wreq = new GetMethodWebRequest(this .url);
072: WebResponse wresp = this .webConv.getResponse(wreq);
073: int responseCode = wresp.getResponseCode();
074: if (responseCode >= 400)
075: throw new IOException("Failed with status "
076: + responseCode);
077: InputStream inContent = wresp.getInputStream();
078: int contentLength = wresp.getContentLength();
079: byte content[] = new byte[contentLength == -1 ? 100 * 1024
080: : contentLength];
081: int position = 0;
082: int value = inContent.read();
083: while ((value != -1)
084: && (((contentLength >= 0) && (position < contentLength)) || (contentLength < 0))) {
085: content[position++] = (byte) value;
086: value = inContent.read();
087: }
088: inContent.close();
089:
090: // Confirm the result is the same size the content-length said it
091: // was
092: if ((position == contentLength) || (contentLength == -1)) {
093: if (this .interrupted)
094: return;
095: this .loadTest.incTimeTotal(System.currentTimeMillis()
096: - startTime);
097: this .loadTest.incSuccessCount();
098: } else
099: throw new IOException("Only downloaded " + position
100: + " of " + contentLength + " bytes");
101: } catch (IOException err) {
102: Logger.log(Logger.DEBUG, resources, "LoadTestThread.Error",
103: err);
104: } catch (SAXException err) {
105: Logger.log(Logger.DEBUG, resources, "LoadTestThread.Error",
106: err);
107: }
108: }
109:
110: public void destroy() {
111: this .interrupted = true;
112: this.thread.interrupt();
113: if (this.next != null)
114: this.next.destroy();
115: }
116: }
|