001: package org.apache.ojb.ejb.pb;
002:
003: /* Copyright 2004-2005 The Apache Software Foundation
004: *
005: * Licensed under the Apache License, Version 2.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: import javax.ejb.EJBHome;
019: import javax.naming.Context;
020: import javax.rmi.PortableRemoteObject;
021: import java.math.BigDecimal;
022: import java.util.ArrayList;
023: import java.util.Iterator;
024: import java.util.List;
025:
026: import org.apache.commons.lang.SystemUtils;
027: import org.apache.ojb.broker.OJBRuntimeException;
028: import org.apache.ojb.ejb.ArticleVO;
029: import org.apache.ojb.ejb.ContextHelper;
030:
031: /**
032: * stress test against one database using several threads
033: *
034: * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>.
035: * @version $Id: StressTest.java,v 1.5.2.1 2005/12/21 22:21:38 tomdz Exp $
036: */
037: public class StressTest {
038: private static int iterationsPerThread = 50;
039: private static int concurrentThreads = 2;
040: private PBSessionRemote bean;
041: private static boolean testClientPass = true;
042:
043: /**
044: * times[0] startTime/test length
045: * times[1] inserting times
046: * times[2] fetching times
047: * times[3] deleting times
048: */
049: private long[] times;
050:
051: /**
052: * The threads that are executing.
053: */
054: private Thread threads[] = null;
055:
056: public StressTest() {
057: }
058:
059: public static void performTest(int[] args) throws Exception {
060: if (args.length > 0) {
061: concurrentThreads = args[0];
062: }
063: if (args.length > 1) {
064: iterationsPerThread = args[1];
065: }
066:
067: StressTest test = new StressTest();
068: int objectCount = 0;
069: int objectCountAfter = 0;
070: test.init();
071: objectCount = test.getArticleCount();
072: test.runMultithreaded();
073:
074: System.out
075: .println("Test-Info: Objects in DB before PB test: "
076: + objectCount);
077: objectCountAfter = test.getArticleCount();
078: System.out.println("Test-Info: Objects in DB after PB test: "
079: + objectCountAfter);
080: System.out
081: .println("Test-Info: Stress test was successful? - "
082: + (objectCount == objectCountAfter && testClientPass)
083: + " -");
084: if (!testClientPass)
085: throw new RuntimeException("Test does not pass");
086: }
087:
088: /**
089: * Setting up the test fixture.
090: */
091: private void init() throws Exception {
092: Context ctx = ContextHelper.getContext();
093: times = new long[4];
094: try {
095: Object object = PortableRemoteObject.narrow(ctx
096: .lookup(PBSessionHome.JNDI_NAME), EJBHome.class);
097: bean = ((PBSessionHome) object).create();
098: } catch (Exception e) {
099: e.printStackTrace(System.err);
100: throw e;
101: }
102: }
103:
104: private int getArticleCount() throws Exception {
105: try {
106: return bean.getArticleCount();
107: } catch (java.rmi.RemoteException e) {
108: e.printStackTrace();
109: throw e;
110: }
111: }
112:
113: private void runMultithreaded() throws Exception {
114: String sep = SystemUtils.LINE_SEPARATOR;
115:
116: System.out.println(sep + sep
117: + "++ Start thread generation for PB api test ++");
118: System.out.println("Begin with performance test, "
119: + concurrentThreads + " concurrent threads, handle "
120: + iterationsPerThread + " articles per thread");
121: PBTestClient[] clientsPB = new PBTestClient[concurrentThreads];
122: for (int i = 0; i < concurrentThreads; i++) {
123: PBTestClient obj = new PBTestClient(this );
124: clientsPB[i] = obj;
125: }
126: System.out.println("");
127: times[0] = System.currentTimeMillis();
128: runTestClients(clientsPB);
129: times[0] = (System.currentTimeMillis() - times[0]);
130: System.out.println(buildTestSummary("PB API"));
131: System.out.println("++ End of performance test PB api ++" + sep
132: + sep);
133: }
134:
135: /**
136: * Interrupt the running threads.
137: */
138: synchronized void interruptThreads() {
139: testClientPass = false;
140: if (threads != null) {
141: for (int i = 0; i < threads.length; i++) {
142: threads[i].interrupt();
143: }
144: }
145: System.err.println("## Test failed! ##");
146: System.err.println("## Test failed! ##");
147: }
148:
149: /**
150: * Run the threads.
151: */
152: void runTestClients(final TestClient[] runnables) throws Exception {
153: if (runnables == null) {
154: throw new IllegalArgumentException("runnables is null");
155: }
156: threads = new Thread[runnables.length];
157: for (int i = 0; i < threads.length; i++) {
158: threads[i] = new Thread(runnables[i]);
159: }
160: for (int i = 0; i < threads.length; i++) {
161: threads[i].start();
162: threads[i].join();
163: }
164: threads = null;
165: }
166:
167: synchronized void addTime(int position, long time) {
168: times[position] = times[position] + time;
169: }
170:
171: private String buildTestSummary(String key) {
172: String sep = System.getProperty("line.separator");
173: StringBuffer buf = new StringBuffer();
174: buf.append(sep);
175: buf
176: .append("----------------------------------------------------");
177: buf.append(sep);
178: buf.append("TEST SUMMARY - " + key);
179: buf.append(sep);
180: buf.append(concurrentThreads + " concurrent threads, handle "
181: + iterationsPerThread + " articles per thread");
182: buf.append(sep);
183: buf.append("Test period: " + (((double) times[0]) / 1000)
184: + " [sec]");
185: buf.append(sep);
186: buf.append("Inserting period: " + times[1] + " [msec]");
187: buf.append(sep);
188: buf.append("Fetching period: " + times[2] + " [msec]");
189: buf.append(sep);
190: buf.append("Deleting period: " + times[3] + " [msec]");
191: buf.append(sep);
192: buf
193: .append("----------------------------------------------------");
194:
195: return buf.toString();
196: }
197:
198: //*********************************************************************************
199: // inner classes
200: //*********************************************************************************
201:
202: static abstract class TestClient implements Runnable {
203:
204: }
205:
206: /**
207: * PB-api test class
208: */
209: static class PBTestClient extends TestClient {
210: private List articlesList;
211: private PBSessionRemote bean;
212: private String articleName;
213: private StressTest test;
214:
215: public PBTestClient(StressTest arg) {
216: test = arg;
217: init();
218: articlesList = new ArrayList();
219: articleName = "PBTestClient_" + System.currentTimeMillis();
220: for (int i = 0; i < iterationsPerThread; i++) {
221: articlesList.add(createArticle(articleName));
222: }
223: }
224:
225: protected void init() {
226: Context ctx = ContextHelper.getContext();
227: try {
228: Object object = PortableRemoteObject
229: .narrow(ctx.lookup(PBSessionHome.JNDI_NAME),
230: EJBHome.class);
231: bean = ((PBSessionHome) object).create();
232: } catch (Exception e) {
233: e.printStackTrace();
234: throw new OJBRuntimeException("Can't lookup bean: "
235: + PBSessionHome.JNDI_NAME, e);
236: }
237: }
238:
239: public void run() {
240: //log.info("Thread "+this+" run");
241: try {
242: insertNewArticles();
243: readAllArticles();
244: deleteArticles();
245: } catch (Throwable e) {
246: System.err
247: .println("Error in client: " + e.getMessage());
248: test.interruptThreads();
249: throw new OJBRuntimeException(
250: "["
251: + PBTestClient.class.getName()
252: + "] Stress test client cause exception, thread was "
253: + Thread.currentThread(), e);
254: }
255: }
256:
257: /**
258: * factory method that createa an ArticleVO
259: * @return the created ArticleVO object
260: */
261: private ArticleVO createArticle(String articleName) {
262: ArticleVO a = new ArticleVO();
263: a.setName(articleName);
264: a.setPrice(new BigDecimal(0.45 * articleName.hashCode()));
265: a.setDescription("description " + articleName.hashCode());
266: return a;
267: }
268:
269: protected void deleteArticles() throws Exception {
270: long start = System.currentTimeMillis();
271:
272: bean.deleteObjects(articlesList);
273:
274: long stop = System.currentTimeMillis();
275: test.addTime(3, stop - start);
276: }
277:
278: protected void insertNewArticles() throws Exception {
279: long start = System.currentTimeMillis();
280:
281: articlesList = bean.storeObjects(articlesList);
282:
283: long stop = System.currentTimeMillis();
284: test.addTime(1, stop - start);
285: }
286:
287: protected void readAllArticles() throws Exception {
288: long start = System.currentTimeMillis();
289:
290: Iterator it = bean.getArticlesByName(articleName)
291: .iterator();
292: while (it.hasNext())
293: it.next();
294:
295: long stop = System.currentTimeMillis();
296: test.addTime(2, stop - start);
297: }
298: }
299: }
|