001: /*
002: * ====================================================================
003: * JAFFA - Java Application Framework For All
004: *
005: * Copyright (C) 2002 JAFFA Development Group
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * Redistribution and use of this software and associated documentation ("Software"),
022: * with or without modification, are permitted provided that the following conditions are met:
023: * 1. Redistributions of source code must retain copyright statements and notices.
024: * Redistributions must also contain a copy of this document.
025: * 2. Redistributions in binary form must reproduce the above copyright notice,
026: * this list of conditions and the following disclaimer in the documentation
027: * and/or other materials provided with the distribution.
028: * 3. The name "JAFFA" must not be used to endorse or promote products derived from
029: * this Software without prior written permission. For written permission,
030: * please contact mail to: jaffagroup@yahoo.com.
031: * 4. Products derived from this Software may not be called "JAFFA" nor may "JAFFA"
032: * appear in their names without prior written permission.
033: * 5. Due credit should be given to the JAFFA Project (http://jaffa.sourceforge.net).
034: *
035: * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: */
049: /*
050: * RunTest.java
051: *
052: * Created on April 15, 2003, 11:11 AM
053: */
054:
055: package org.jaffa.tools.loadtest;
056:
057: import org.apache.log4j.Logger;
058: import org.jaffa.tools.loadtest.domain.*;
059: import org.jaffa.datatypes.DateTime;
060: import java.util.Iterator;
061:
062: import java.util.*;
063: import java.lang.Thread;
064: import java.io.Writer;
065: import java.io.FileWriter;
066: import java.io.IOException;
067: import java.lang.Runtime;
068: import java.lang.reflect.*;
069: import java.lang.Class;
070: import com.meterware.httpunit.WebConversation;
071: import com.meterware.httpunit.WebResponse;
072: import org.xml.sax.SAXException;
073: import junit.framework.TestCase;
074:
075: /**
076: *
077: * @author MaheshD
078: */
079: public class RunTestSet extends Thread {
080:
081: /** Set up Logging for Log4J */
082: private static Logger log = Logger.getLogger(RunTestSet.class);
083:
084: private TestSet m_testSet = null;
085: private int threadNumber;
086: private TestResultLogger writer;
087:
088: private WebConversation conversation = new WebConversation();
089: private WebResponse loggedOn = null;
090:
091: /** Creates a new instance of RunTest and performs Logon
092: * @param ts TestSet object
093: * @param count Thread Number
094: * @param resultLog TestResultLogger object to write the result to the file
095: */
096: public RunTestSet(TestSet ts, int threadCount,
097: TestResultLogger resultLog) {
098: m_testSet = ts;
099: writer = resultLog;
100: threadNumber = threadCount;
101: if (m_testSet == null) {
102: throw new RuntimeException("Can't initialize TestSet !");
103: }
104:
105: loggedOn = performLogon(ts.getLogOn(), this .conversation);
106:
107: if (loggedOn == null) {
108: throw new RuntimeException("Failed To Log On");
109: }
110:
111: }
112:
113: /** Executes the TestSet based on the
114: * parameteres set like no of Iterations, TestCase
115: * If the selectionis random , it picks up a random number and calls the unti tests
116: *or else it runs the unti tests sequentially.
117: */
118: public void run() {
119: //Batch size indicates Total number of tests to be run by each thread
120: String random = "random";
121:
122: int batchSize = m_testSet.getBatchSize().intValue();
123: // delay indicates the delay between each tests.
124: int delay = m_testSet.getRunDelay().intValue();
125: String selection = m_testSet.getSelection();
126: List unitTests = m_testSet.getUnitTests().getUnitTest();
127: int count = 1;
128: if (random.equalsIgnoreCase(selection)) {
129: Random myRandom = new Random();
130: while (batchSize != 0) {
131: int randomInt = myRandom.nextInt(unitTests.size());
132: this .runUnitTest((UnitTest) unitTests.get(randomInt),
133: count++);
134: batchSize--;
135: }
136: } else {
137: while (batchSize != 0) {
138: for (int i = 0; i < unitTests.size(); batchSize--, i++) {
139: if (batchSize == 0) {
140: break;
141: }
142: this .runUnitTest((UnitTest) unitTests.get(i),
143: count++);
144: }
145: }
146: }
147: this .performLogout(conversation, m_testSet.getLogOn()
148: .getWebappRoot());
149: }
150:
151: /** Runs the UntiTest invoking the unit test specified in the xml file
152: * @param unittest unittest to be run
153: * @param count iteration number
154: */
155: private void runUnitTest(UnitTest unittest, int count) {
156: String className = new String();
157: String methodName = new String();
158: try {
159: className = unittest.getClassName();
160: Class clazz = Class.forName(className);
161: Class tclass = Class.forName("junit.framework.TestCase");
162: Class iclass = Class
163: .forName("org.jaffa.tools.loadtest.ILoadTestCase");
164: String param = className + ".class";
165:
166: Object obj = clazz.getConstructor(
167: new Class[] { String.class }).newInstance(
168: new Object[] { param });
169:
170: methodName = unittest.getMethodName();
171: Method method = clazz.getDeclaredMethod(methodName, null);
172: // Initalize
173: /*
174: if(tclass.isInstance(obj)) {
175: //setUp();
176: }*/
177:
178: // Validate Class Implements ILoadTestCase
179: if (iclass.isInstance(obj)) {
180: String setWC = "setWebConversation";
181: String setResp = "setWebResponse";
182:
183: Method setWcMethod = clazz.getMethod(setWC,
184: new Class[] { WebConversation.class });
185: Method setRespMethod = clazz.getMethod(setResp,
186: new Class[] { WebResponse.class });
187: setWcMethod.invoke(obj,
188: new Object[] { this .conversation });
189: setRespMethod.invoke(obj,
190: new Object[] { this .loggedOn });
191: }
192:
193: long startTime = System.currentTimeMillis();
194: DateTime startdt = new DateTime(startTime);
195: method.invoke(obj, null);
196: long endTime = System.currentTimeMillis();
197: DateTime enddt = new DateTime(endTime);
198:
199: // un-initalize
200: /*if(tclass.isInstance(obj)) {
201: //teardown();
202: }*/
203:
204: long duration = endTime - startTime;
205: synchronized (this ) {
206: writer.output(threadNumber, count, startdt.toString(),
207: enddt.toString(), Long.toString(duration),
208: className + "." + methodName, "Success");
209: }
210: Thread.sleep(m_testSet.getRunDelay().intValue());
211: } catch (InstantiationException e) {
212: e.printStackTrace();
213: } catch (NoSuchMethodException e) {
214: log.error("No such Method - " + e.getMessage());
215: } catch (IllegalAccessException e) {
216: e.printStackTrace();
217: } catch (ClassNotFoundException e) {
218: log.error("Can't find Class - " + e.getMessage());
219: } catch (InvocationTargetException e) {
220: synchronized (this ) {
221: writer.output(threadNumber, count, "", "", "",
222: className + "." + methodName, "Failure");
223: }
224: e.printStackTrace();
225: } catch (InterruptedException e) {
226: e.printStackTrace();
227: }
228:
229: }
230:
231: /** Logs on to the system based on the Logon Class specified in the xml file
232: * @param logOn LogOn object which contains the List of users who can log on and run the tests
233: * @param wc WebConversation object to get the response
234: * @return returns the WebResponse object if sucessfully logged in. Or else returns null
235: */
236: private WebResponse performLogon(LogOn logOn, WebConversation wc) {
237: try {
238: Class clazz = Class.forName(logOn.getClassName());
239: ILoadTesterLogOn logObj = (ILoadTesterLogOn) clazz
240: .newInstance();
241:
242: User user = pickUser(logOn.getUsers().getUser());
243:
244: WebResponse r = logObj.logOn(wc, logOn.getWebappRoot(),
245: user.getName(), user.getPassword(), logOn
246: .getLoggedOnTitle());
247: if (logOn.getLoggedOnTitle() != null) {
248: try {
249: if (!logOn.getLoggedOnTitle().equalsIgnoreCase(
250: r.getTitle())) {
251: log.error("Log On Failed For - "
252: + user.getName() + "/"
253: + user.getPassword());
254: return null;
255: }
256: } catch (SAXException e) {
257: log.error("Log On Failed For - " + user.getName()
258: + "/" + user.getPassword(), e);
259: return null;
260: }
261: }
262: return r;
263: } catch (ClassNotFoundException e) {
264: log.error("Can't find Log On Class Implementation - "
265: + logOn.getClassName());
266: } catch (IllegalAccessException e) {
267: log.error("Can't create Log On Class Implementation - "
268: + e.getMessage());
269: } catch (InstantiationException e) {
270: log.error("Can't create Log On Class Implementation - "
271: + e.getMessage());
272: } catch (ClassCastException e) {
273: log.error("Log On Class Implements Wrong Interface");
274: }
275: return null;
276: }
277:
278: /** Logs off from the System
279: * @param wc WebConversation to get the response
280: * @param webRoot url from which the system needs to be logged off.
281: */
282: private void performLogout(WebConversation wc, String webRoot) {
283: try {
284: Class clazz = Class.forName(m_testSet.getLogOn()
285: .getClassName());
286: ILoadTesterLogOn logObj = (ILoadTesterLogOn) clazz
287: .newInstance();
288:
289: logObj.logOff(wc, webRoot);
290:
291: } catch (ClassNotFoundException e) {
292: log.error("Can't find Log On Class Implementation - "
293: + m_testSet.getLogOn().getClassName());
294: } catch (InstantiationException e) {
295: log.error("Can't create Log On Class Implementation - "
296: + e.getMessage());
297: } catch (IllegalAccessException e) {
298: log.error("Can't create Log On Class Implementation - "
299: + e.getMessage());
300: }
301: }
302:
303: private User pickUser(List users) {
304: Random myRandom = new Random();
305: int randomNumber = myRandom.nextInt(users.size());
306: return (User) users.get(randomNumber);
307: }
308:
309: }
|