001: package org.apache.ojb.performance;
002:
003: /* Copyright 2002-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 java.util.Collection;
019: import java.util.Iterator;
020:
021: /**
022: * Derivate this class to implement a test client for the performance test.
023: *
024: * @version $Id: PerfTest.java,v 1.9.2.5 2005/12/30 00:01:42 arminw Exp $
025: */
026: public abstract class PerfTest implements Runnable {
027: private String PREFIX_LOG = "[" + this .getClass().getName() + "] ";
028: private PerfRunner test;
029: private String objectName;
030:
031: public PerfTest() {
032: }
033:
034: /**
035: * Returns the name of the test
036: */
037: public abstract String testName();
038:
039: /**
040: * Returns the count of all found {@link PerfArticle}
041: * in database.
042: * This method is not involved in the performance test
043: * methods, thus it's not mandatory to use the api-methods
044: * for implementation.
045: */
046: public abstract int articleCount();
047:
048: /**
049: * Init the test. do setup stuff here
050: */
051: public abstract void init() throws Exception;
052:
053: /**
054: * Do clean up.
055: */
056: public abstract void tearDown() throws Exception;
057:
058: /**
059: * Store the given articles to database. Do optimize
060: * performance.
061: */
062: public abstract void insertNewArticles(PerfArticle[] arr)
063: throws Exception;
064:
065: /**
066: * Store the given articles to database. Implement a really
067: * resource stressing way.
068: */
069: public abstract void insertNewArticlesStress(PerfArticle[] arr)
070: throws Exception;
071:
072: /**
073: * Read all stored articles from the database and return the
074: * result as collection of <code>PerfArticles</code>.
075: * Do optimize performance.
076: * @param articleName article name used for all {@link PerfArticle} created
077: * by this instance/thread. Use this name in your query to match all belonging articles
078: */
079: public abstract Collection readArticlesByCursor(String articleName)
080: throws Exception;
081:
082: /**
083: * Read all stored articles from the database and return the
084: * result as collection of <code>PerfArticles</code>.
085: * Do optimize performance.
086: * @param articleId the primary key of a {@link PerfArticle} instance
087: * @return The matching {@link PerfArticle} instance or <em>null</em> if not found.
088: */
089: public abstract PerfArticle getArticleByIdentity(Long articleId)
090: throws Exception;
091:
092: /**
093: * Delete all given article from the database.
094: * Do optimize performance.
095: */
096: public abstract void deleteArticles(PerfArticle[] arr)
097: throws Exception;
098:
099: /**
100: * Delete all given article from the database in a really resource
101: * sressing way.
102: */
103: public abstract void deleteArticlesStress(PerfArticle[] arr)
104: throws Exception;
105:
106: /**
107: * Update the given articles. Do optimize
108: * performance.
109: */
110: public abstract void updateArticles(PerfArticle[] arr)
111: throws Exception;
112:
113: /**
114: * Update the given articles. Implement a really
115: * resource stressing way.
116: */
117: public abstract void updateArticlesStress(PerfArticle[] arr)
118: throws Exception;
119:
120: /**
121: * Called to get a new instance class of the {@link org.apache.ojb.performance.PerfArticle}
122: * interface, override this method if you need your own implementation
123: * (with default constructor) of the PerfArticle-Interface.
124: * <br/>
125: * By default this method returns a new instance of the
126: * {@link org.apache.ojb.performance.PerfArticleImpl} class.
127: *
128: */
129: public PerfArticle newPerfArticle() {
130: return new PerfArticleImpl();
131: }
132:
133: /**
134: * The returned name was used as 'articleName' for all
135: * created <code>PerfArticles</code> for this thread.
136: * This allows an easy build of the query statement
137: * to match the created {@link PerfArticle} for this
138: * instance/thread.
139: */
140: public String getTestObjectName() {
141: if (objectName == null)
142: objectName = testName() + "_"
143: + Thread.currentThread().toString() + "_"
144: + test.getPerfTestId();
145: return objectName;
146: }
147:
148: /**
149: * Factory method that creates an {@link org.apache.ojb.performance.PerfArticle}
150: * using the {@link org.apache.ojb.performance.PerfArticleImpl} class,
151: * override this method if you need your own implementation
152: * of the PerfArticle-Interface.
153: *
154: * @param articleName set the 'articleName'
155: * @return the created PerfArticle object
156: */
157: public PerfArticle getPreparedPerfArticle(String articleName) {
158: PerfArticle a = newPerfArticle();
159: a.setArticleName(articleName);
160: a.setMinimumStock(100);
161: a.setPrice(0.45);
162: a.setProductGroupId(1);
163: a.setStock(234);
164: a.setSupplierId(4);
165: a.setUnit("bottle");
166: return a;
167: }
168:
169: void setPerfRunner(PerfRunner test) {
170: this .test = test;
171: }
172:
173: /**
174: * Runnable implementation method.
175: */
176: public void run() {
177: PerfArticle[] m_arr = new PerfArticle[PerfMain
178: .getIterationsPerThread()];
179: for (int i = 0; i < PerfMain.getIterationsPerThread(); i++) {
180: m_arr[i] = getPreparedPerfArticle(getTestObjectName());
181: }
182:
183: try {
184: long totalTime = 0;
185: long period;
186: init();
187:
188: // insert objects
189: if (PerfMain.isUseStressMode()) {
190: period = System.currentTimeMillis();
191: insertNewArticlesStress(m_arr);
192: period = System.currentTimeMillis() - period;
193: test.addTime(PerfMain.TIME_INSERT, period);
194: totalTime += period;
195: } else {
196: period = System.currentTimeMillis();
197: insertNewArticles(m_arr);
198: period = System.currentTimeMillis() - period;
199: test.addTime(PerfMain.TIME_INSERT, period);
200: totalTime += period;
201: // System.out.println("I=" + period);
202: }
203: checkInsertResult(m_arr);
204:
205: // read objects
206: period = System.currentTimeMillis();
207: Collection col = readArticlesByCursor(objectName);
208: period = System.currentTimeMillis() - period;
209: try {
210: checkQueryResult(col, m_arr);
211: } catch (Exception e) {
212: test
213: .registerException(
214: PREFIX_LOG
215: + "(Something wrong with query result or with object insert operation) ",
216: e);
217: }
218: test.addTime(PerfMain.TIME_FETCH, period);
219: totalTime += period;
220: // System.out.println("R=" + period);
221:
222: // read objects 2
223: period = System.currentTimeMillis();
224: col = readArticlesByCursor(objectName);
225: period = System.currentTimeMillis() - period;
226: try {
227: checkQueryResult(col, m_arr);
228: } catch (Exception e) {
229: test
230: .registerException(
231: PREFIX_LOG
232: + "(Something wrong with query result or with object insert operation) ",
233: e);
234: }
235: test.addTime(PerfMain.TIME_FETCH_2, period);
236: totalTime += period;
237: // System.out.println("R2=" + period);
238:
239: // get by Identity
240: period = System.currentTimeMillis();
241: PerfArticle result;
242: for (int i = 0; i < m_arr.length; i++) {
243: if (i % 4 == 0) {
244: PerfArticle perfArticle = m_arr[i];
245: result = getArticleByIdentity(perfArticle
246: .getArticleId());
247: if (result == null) {
248: test.registerException(
249: "Unexpected result: Get by Identity is 'null' for "
250: + PerfArticle.class.getName()
251: + " with primary key "
252: + perfArticle.getArticleId(),
253: null);
254: }
255: }
256: }
257: period = (System.currentTimeMillis() - period);
258: test.addTime(PerfMain.TIME_BY_IDENTITY, period);
259: totalTime += period;
260: // System.out.println("B=" + period);
261:
262: // update objects
263: modifyPerfArticle(m_arr);
264: if (PerfMain.isUseStressMode()) {
265: period = System.currentTimeMillis();
266: updateArticlesStress(m_arr);
267: period = System.currentTimeMillis() - period;
268: test.addTime(PerfMain.TIME_UPDATE, period);
269: totalTime += period;
270: } else {
271: period = System.currentTimeMillis();
272: updateArticles(m_arr);
273: period = System.currentTimeMillis() - period;
274: test.addTime(PerfMain.TIME_UPDATE, period);
275: totalTime += period;
276: // System.out.println("U=" + period);
277: }
278:
279: // delete objects
280: if (PerfMain.isUseStressMode()) {
281: period = System.currentTimeMillis();
282: deleteArticlesStress(m_arr);
283: period = System.currentTimeMillis() - period;
284: test.addTime(PerfMain.TIME_DELETE, period);
285: totalTime += period;
286: } else {
287: period = System.currentTimeMillis();
288: deleteArticles(m_arr);
289: period = System.currentTimeMillis() - period;
290: test.addTime(PerfMain.TIME_DELETE, period);
291: totalTime += period;
292: // System.out.println("D=" + period);
293: }
294: test.addTime(PerfMain.TIME_TOTAL, totalTime);
295: tearDown();
296: } catch (Exception e) {
297: e.printStackTrace();
298: test.registerException(PREFIX_LOG
299: + "(Unexpected behaviour) ", e);
300: test.interruptThreads();
301: }
302: }
303:
304: private void modifyPerfArticle(PerfArticle[] m_arr) {
305: PerfArticle article;
306: String prefix = "updated_";
307: for (int i = 0; i < m_arr.length; i++) {
308: article = m_arr[i];
309: article.setArticleName(prefix + article.getArticleName());
310: }
311: }
312:
313: private void checkQueryResult(Collection col, PerfArticle[] m_arr)
314: throws Exception {
315: if (col.size() > 0) {
316: Iterator it = col.iterator();
317: Object obj = it.next();
318: if (!(obj instanceof PerfArticle)) {
319: throw new Exception(
320: "Wrong object type found. Expected instance of"
321: + PerfArticle.class.getName()
322: + ", found " + obj.getClass().getName());
323: }
324: }
325: if (col.size() != m_arr.length) {
326: throw new Exception(
327: "Read objects: Wrong number of objects found. Expected "
328: + (m_arr.length) + ", found " + col.size());
329: }
330: }
331:
332: private void checkInsertResult(PerfArticle[] m_arr)
333: throws Exception {
334: for (int i = 0; i < m_arr.length; i++) {
335: PerfArticle perfArticle = m_arr[i];
336: if (perfArticle.getArticleId() == null) {
337: throw new Exception(
338: "Insert objects: Object with 'null' PK found");
339: }
340: }
341: }
342: }
|