adding all of botlist, initial add
[botlist.git] / openbotlist / tests / system / loadhttptest / src / org / spirit / loadtest / LoadTestSequenceParser.java
bloba031d999ec1535eaf51b531b36b262c7b48494ce
1 /*
2 * Created on Jul 20, 2007
3 */
4 package org.spirit.loadtest;
6 import java.net.HttpURLConnection;
7 import java.net.URL;
8 import java.util.ArrayList;
9 import java.util.HashMap;
10 import java.util.Iterator;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Random;
15 /**
16 * Sequence Format File should contain the following format:
18 * METHOD_TYPE, URL, <DATA if POST enabled, separated by ';' semicolon [key=value]>
21 public class LoadTestSequenceParser {
23 private List sequenceData = new ArrayList();
25 private static final String REQUEST_GET = "GET";
26 private static final String REQUEST_POST = "POST";
28 private static final String COMMAND_SLEEP = "SLEEP";
30 private static final String TEMPLATE_COMMAND_RAND = "100";
32 public static final String [][] TEMPLATE_COMMANDS = {
33 { "RAND", TEMPLATE_COMMAND_RAND }
36 private final String START_TOKEN = "{";
37 private final String END_TOKEN = "}";
39 private Random randObj = new Random();
40 private final int MAX_RAND_INT = 10000;
42 public List getSequenceData() {
43 return sequenceData;
46 /**
47 * When certain template parameters are found within sequence scripts,
48 * parse them accordingly.
50 * For example; http://www.yahoo{RAND#100}.com
52 * Will replace the variable with a random integer number between 0 and 100.
54 * @return
56 public String processTemplateVars(final String var) {
57 int startIndex = var.indexOf(START_TOKEN);
58 int endIndex = var.indexOf(END_TOKEN);
59 if ((endIndex > startIndex) && (startIndex >= 0)) {
60 String templateVals = var.substring(startIndex, endIndex);
61 String res = parseTemplateVars(templateVals);
62 // Replace the template variable with a value.
63 if (res != null) {
64 return var.substring(0, startIndex) + res + var.substring(endIndex + 1);
67 return null;
70 /**
71 * Return the system command code based on the input template variable.
73 * For example, RAND = system code 100 return value.
75 * @param var
76 * @return
78 public String parseTemplateVars(final String var) {
79 for (int i = 0; i < TEMPLATE_COMMANDS.length; i++) {
80 String systemCommand = TEMPLATE_COMMANDS[i][0];
81 String systemCode = TEMPLATE_COMMANDS[i][1];
82 String templateCommand = var.substring(1, var.length());
83 if (systemCommand.equalsIgnoreCase(templateCommand)) {
84 if (TEMPLATE_COMMAND_RAND.equalsIgnoreCase(systemCode)) {
85 return "" + randObj.nextInt(MAX_RAND_INT);
87 } // End of if - system command / template command
89 return null;
92 public void parse(final String sequence_file) {
93 Object data [] = LoadTestManager.loadDataFile(sequence_file);
94 for (int i = 0; i < data.length; i++) {
95 String [] tokens = ((String) data[i]).split(",");
96 if ((tokens.length == 2) || (tokens.length == 3)) {
97 SequenceModel model = new SequenceModel();
98 String action = tokens[0].trim();
99 model.setActionMethod(tokens[0].trim());
100 model.setRequestUrl(tokens[1].trim());
101 if (action.equalsIgnoreCase(REQUEST_POST)) {
102 // Load the POST content
103 String postDataStr = tokens[2].trim();
104 String postData [] = postDataStr.split(";");
105 for (int k = 0; k < postData.length; k++) {
106 String key_val = postData[k];
107 int eq_idx = key_val.indexOf("=");
108 String key = key_val.substring(0, eq_idx).trim();
109 String val = key_val.substring(eq_idx + 1).trim();
111 // Template (variable replace) the key and/or value string values
112 String parseKey = processTemplateVars(key);
113 String parseVal = processTemplateVars(val);
114 key = (parseKey != null) ? parseKey : key;
115 val = (parseVal != null) ? parseVal : val;
116 model.putPostData(key, val);
119 // Add the sequence model to the current set of data
120 sequenceData.add(model);
121 } else {
122 throw new RuntimeException("Invalid Sequence Data Format, format tokens=" + tokens.length);
124 } // End of the For
126 System.out.println("INFO: " + sequenceData.size() + " requests found in sequence");
128 public void printSummary() {
129 for (Iterator it = sequenceData.iterator(); it.hasNext();) {
130 SequenceModel statement = (SequenceModel) it.next();
131 System.out.println(statement);
135 private String [] handleGETRequest(SequenceModel statement, final boolean loadExistingCookies) {
136 String responseTuple [] = { "" , "", "" };
137 String url = statement.getRequestUrl();
138 if (url != null && url.toLowerCase().startsWith("https")) {
139 // Connect with SSL connection
140 System.out.println("INFO: attempting connect with SSL connection");
141 responseTuple = LoadTestManager.connectURLSSL(url, loadExistingCookies);
142 } else {
143 responseTuple = LoadTestManager.connectURL(url, loadExistingCookies);
144 } // End of the if
145 return responseTuple;
148 private String [] handlePOSTRequest(SequenceModel statement, final boolean loadExistingCookies) throws Exception {
149 String responseTuple [] = { "" , "", "" };
150 String str_url = statement.getRequestUrl();
152 URL url = LoadTestManager.getSSLURL(str_url);
153 HttpURLConnection.setFollowRedirects(false);
154 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
155 LoadTestManager.postDataSSL(statement.getPostData(), conn, url, str_url, false, loadExistingCookies);
156 System.out.println("done posting SSL data");
158 return responseTuple;
161 private void handleSleepCommand(SequenceModel statement) {
162 String time_ms = statement.getRequestUrl();
163 int sleepTime = Integer.parseInt(time_ms);
164 try {
165 Thread.sleep(sleepTime);
166 } catch (InterruptedException e) {
171 * Handle all of the sequence statements and perform the according requests.
173 public void handleSequence() {
174 int sequenceNo = 0;
175 for (Iterator it = this.sequenceData.iterator(); it.hasNext();) {
176 boolean loadExistingCookies = (sequenceNo == 0) ? false : true;
177 String responseTuple [] = { "", "", "" };
178 SequenceModel statement = (SequenceModel) it.next();
179 long tStart = System.currentTimeMillis();
180 if (statement.getActionMethod().equalsIgnoreCase(REQUEST_GET)) {
181 System.out.println("seq=[" + sequenceNo + "] attempting GET request to=" + statement.getRequestUrl());
182 responseTuple = handleGETRequest(statement, loadExistingCookies);
183 LoadTestManager.getTestClient().incNumberOfRequests();
184 } else if (statement.getActionMethod().equalsIgnoreCase(REQUEST_POST)) {
185 System.out.println("seq=[" + sequenceNo + "] attempting POST request to=" + statement.getRequestUrl());
186 try {
187 responseTuple = handlePOSTRequest(statement, loadExistingCookies);
188 } catch(Exception e) {
189 e.printStackTrace();
191 LoadTestManager.getTestClient().incNumberOfRequests();
192 } else if (statement.getActionMethod().equalsIgnoreCase(COMMAND_SLEEP)) {
193 // Delay for X number of milliseconds when a sleep command is found
194 handleSleepCommand(statement);
195 } else {
196 throw new RuntimeException("Action method not supported=" + statement.getActionMethod());
199 long tEnd = System.currentTimeMillis();
200 long diff = tEnd - tStart;
202 // For data keeping, increment total requests
203 LoadTestManager.getTestClient().incTotalTime(diff);
205 System.out.println("single request time=" + diff + " ms -- from thread:" + Thread.currentThread().getName());
206 LoadTestManager.log(diff, responseTuple, statement.getRequestUrl());
208 // The following code buildRequestSection, clearRequest are needed after writing the HTML content
209 LoadTestManager.getTestClient().getHtmlOutput().buildRequestSection(diff + " ms, requests=" + sequenceNo);
210 LoadTestManager.getTestClient().getHtmlOutput().clearRequest();
211 sequenceNo++;
215 public class SequenceModel {
216 private String actionMethod = "GET";
217 private String requestUrl = "http://localhost";
218 private Map postData = new HashMap();
219 public String getActionMethod() {
220 return actionMethod;
223 public Map getPostData() {
224 return postData;
227 public String getRequestUrl() {
228 return requestUrl;
230 public void setActionMethod(String string) {
231 actionMethod = string;
233 public void putPostData(final String key, final String val) {
234 this.postData.put(key, val);
236 public void setRequestUrl(String string) {
237 requestUrl = string;
239 public String toString() {
240 return "SequenceModel: action=[" + actionMethod + "], url=[" + requestUrl + "], data=[" + postData + "]";
245 // End of File