001: package org.apache.ojb.ejb.odmg;
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:39 tomdz Exp $
036: */
037: public class StressTest {
038: private static int iterationsPerThread = 50;
039: private static int concurrentThreads = 2;
040: private ODMGSessionRemote 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 ODMG test: "
076: + objectCount);
077: objectCountAfter = test.getArticleCount();
078: System.out
079: .println("Test-Info: Objects in DB after ODMG test: "
080: + objectCountAfter);
081: System.out
082: .println("Test-Info: Stress test was successful? - "
083: + (objectCount == objectCountAfter && testClientPass)
084: + " -");
085: if (!testClientPass)
086: throw new RuntimeException("Test does not pass");
087: }
088:
089: /**
090: * Setting up the test fixture.
091: */
092: private void init() throws Exception {
093: Context ctx = ContextHelper.getContext();
094: times = new long[4];
095: try {
096: Object object = PortableRemoteObject.narrow(ctx
097: .lookup(ODMGSessionHome.JNDI_NAME), EJBHome.class);
098: bean = ((ODMGSessionHome) object).create();
099: } catch (Exception e) {
100: e.printStackTrace(System.err);
101: throw e;
102: }
103: }
104:
105: private int getArticleCount() throws Exception {
106: try {
107: return bean.getArticleCount();
108: } catch (java.rmi.RemoteException e) {
109: e.printStackTrace();
110: throw e;
111: }
112: }
113:
114: private void runMultithreaded() throws Exception {
115: String sep = SystemUtils.LINE_SEPARATOR;
116:
117: System.out.println(sep + sep
118: + "++ Start thread generation for ODMG api test ++");
119: System.out.println("Begin with performance test, "
120: + concurrentThreads + " concurrent threads, handle "
121: + iterationsPerThread + " articles per thread");
122: ODMGTestClient[] clientsODMG = new ODMGTestClient[concurrentThreads];
123: for (int i = 0; i < concurrentThreads; i++) {
124: ODMGTestClient obj = new ODMGTestClient(this );
125: clientsODMG[i] = obj;
126: }
127: System.out.println("");
128: times[0] = System.currentTimeMillis();
129: runTestClients(clientsODMG);
130: times[0] = (System.currentTimeMillis() - times[0]);
131: System.out.println(buildTestSummary("ODMG API"));
132: System.out.println("++ End of performance test ODMG api ++"
133: + sep + sep);
134: }
135:
136: /**
137: * Interrupt the running threads.
138: */
139: synchronized void interruptThreads() {
140: testClientPass = false;
141: if (threads != null) {
142: for (int i = 0; i < threads.length; i++) {
143: threads[i].interrupt();
144: }
145: }
146: System.err.println("## Test failed! ##");
147: System.err.println("## Test failed! ##");
148: }
149:
150: /**
151: * Run the threads.
152: */
153: void runTestClients(final TestClient[] runnables) throws Exception {
154: if (runnables == null) {
155: throw new IllegalArgumentException("runnables is null");
156: }
157: threads = new Thread[runnables.length];
158: for (int i = 0; i < threads.length; i++) {
159: threads[i] = new Thread(runnables[i]);
160: }
161: for (int i = 0; i < threads.length; i++) {
162: threads[i].start();
163: threads[i].join();
164: }
165: threads = null;
166: }
167:
168: synchronized void addTime(int position, long time) {
169: times[position] = times[position] + time;
170: }
171:
172: private String buildTestSummary(String key) {
173: String sep = System.getProperty("line.separator");
174: StringBuffer buf = new StringBuffer();
175: buf.append(sep);
176: buf
177: .append("----------------------------------------------------");
178: buf.append(sep);
179: buf.append("TEST SUMMARY - " + key);
180: buf.append(sep);
181: buf.append(concurrentThreads + " concurrent threads, handle "
182: + iterationsPerThread + " articles per thread");
183: buf.append(sep);
184: buf.append("Test period: " + (((double) times[0]) / 1000)
185: + " [sec]");
186: buf.append(sep);
187: buf.append("Inserting period: " + times[1] + " [msec]");
188: buf.append(sep);
189: buf.append("Fetching period: " + times[2] + " [msec]");
190: buf.append(sep);
191: buf.append("Deleting period: " + times[3] + " [msec]");
192: buf.append(sep);
193: buf
194: .append("----------------------------------------------------");
195:
196: return buf.toString();
197: }
198:
199: //*********************************************************************************
200: // inner classes
201: //*********************************************************************************
202:
203: static abstract class TestClient implements Runnable {
204:
205: }
206:
207: /**
208: * ODMG-api test class
209: */
210: static class ODMGTestClient extends TestClient {
211: private List articlesList;
212: private ODMGSessionRemote bean;
213: private String articleName;
214: private StressTest test;
215:
216: public ODMGTestClient(StressTest test) {
217: this .test = test;
218: init();
219: articlesList = new ArrayList();
220: articleName = "ODMGTestClient_"
221: + System.currentTimeMillis();
222: for (int i = 0; i < iterationsPerThread; i++) {
223: articlesList.add(createArticle(articleName));
224: }
225: }
226:
227: protected void init() {
228: Context ctx = ContextHelper.getContext();
229: try {
230: Object object = PortableRemoteObject.narrow(ctx
231: .lookup(ODMGSessionHome.JNDI_NAME),
232: EJBHome.class);
233: bean = ((ODMGSessionHome) object).create();
234: } catch (Exception e) {
235: e.printStackTrace();
236: throw new OJBRuntimeException("Can't lookup bean: "
237: + ODMGSessionHome.JNDI_NAME, e);
238: }
239: }
240:
241: public void run() {
242: //log.info("Thread "+this+" run");
243: try {
244: insertNewArticles();
245: readAllArticles();
246: deleteArticles();
247: } catch (Throwable e) {
248: System.err
249: .println("Error in client: " + e.getMessage());
250: test.interruptThreads();
251: throw new OJBRuntimeException(
252: "["
253: + ODMGTestClient.class.getName()
254: + "] Stress test client cause exception, thread was "
255: + Thread.currentThread(), e);
256: }
257: }
258:
259: /**
260: * factory method that createa an ArticleVO
261: * @return the created ArticleVO object
262: */
263: private ArticleVO createArticle(String articleName) {
264: ArticleVO a = new ArticleVO();
265: a.setName(articleName);
266: a.setPrice(new BigDecimal(0.45 * articleName.hashCode()));
267: a.setDescription("description " + articleName.hashCode());
268: return a;
269: }
270:
271: protected void deleteArticles() throws Exception {
272: long start = System.currentTimeMillis();
273:
274: bean.deleteObjects(articlesList);
275:
276: long stop = System.currentTimeMillis();
277: test.addTime(3, stop - start);
278: }
279:
280: protected void insertNewArticles() throws Exception {
281: long start = System.currentTimeMillis();
282:
283: articlesList = bean.storeObjects(articlesList);
284:
285: long stop = System.currentTimeMillis();
286: test.addTime(1, stop - start);
287: }
288:
289: protected void readAllArticles() throws Exception {
290: long start = System.currentTimeMillis();
291:
292: Iterator it = bean.getArticlesByName(articleName)
293: .iterator();
294: while (it.hasNext())
295: it.next();
296:
297: long stop = System.currentTimeMillis();
298: test.addTime(2, stop - start);
299: }
300: }
301: }
|