KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > performance > SpeedTest


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2002 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "WSIF" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 2001, 2002, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57 package performance;
58
59 import java.io.File JavaDoc;
60 import java.io.FileInputStream JavaDoc;
61 import java.io.FileOutputStream JavaDoc;
62 import java.util.Enumeration JavaDoc;
63 import java.util.HashMap JavaDoc;
64 import java.util.Iterator JavaDoc;
65 import java.util.Properties JavaDoc;
66
67 import junit.framework.Test;
68 import junit.framework.TestCase;
69 import junit.framework.TestSuite;
70
71 import org.apache.wsif.WSIFMessage;
72 import org.apache.wsif.WSIFOperation;
73 import org.apache.wsif.WSIFPort;
74 import org.apache.wsif.WSIFService;
75 import org.apache.wsif.WSIFServiceFactory;
76 import org.apache.wsif.base.WSIFServiceImpl;
77 import org.apache.wsif.providers.soap.apacheaxis.WSIFDynamicProvider_ApacheAxis;
78 import org.apache.wsif.util.WSIFPluggableProviders;
79
80 import util.TestUtilities;
81
82 import addressbook.wsiftypes.Address;
83 import addressbook.wsiftypes.Phone;
84
85 /**
86  * Junit test to measure some simple performance statistics.
87  * It times a number of iterations of getPort, createOperation,
88  * and executeRequestResponseOperation for each provider. The
89  * results are stored in a properties file to allow each run
90  * to test if the performance has changed since the last run.
91  *
92  * The number of iterations to do is determined by the time
93  * each test takes and the TIME_PER_TEST constant. You need
94  * to run it atleast 3 times to get the iterations calculation
95  * to settle on a good value; The MARGIN_OF_ERROR constant
96  * defines how mush variation between run times is ignored
97  * when determining if the performance has changed.
98  *
99  * You may need to change the TIME_PER_TEST and MARGIN_OF_ERROR
100  * constants for your machine speed.
101  *
102  * For testing you can add futher timing points to the internal
103  * WSIF classes which this test will then monitor and report on.
104  *
105  * For example, to time the axis provider invoke method, at the
106  * start of the invoke method add:
107  * Monitor.start( "axisInvoke" );
108  * followed by a stop call at the end of the invoke method:
109  * Monitor.stop( "axisInvoke" );
110  *
111  * Monitor points can be paused around unwanted code. For example
112  * with the above monitors in the invoke method, you could exclude
113  * the SOAP call time with:
114  * Monitor.pause( "axisInvoke" );
115  * resp = call.invoke(locationUri, getSoapActionURI());
116  * Monitor.resume( "axisInvoke" );
117  *
118  * @author <a HREF="mailto:antelder@apache.org">Ant Elder</a>
119  */

120 public class SpeedTest extends TestCase {
121
122     // This defines how long each test should be run for.
123
// There are 3 tests per provider; getPort, createOperation
124
// and executeOperation, so the total runnning time will be
125
// 3 times this value, times the number of providers tested.
126
static final float TIME_PER_TEST = 20000.0F; // 1 minute
127

128     // This defines the time variation between runs before a
129
// result is considered a significant performance change.
130
// System.currentTimeMillis() is only acurate to 10msecs
131
// so for this to work you need to run enough iterations
132
static final float MARGIN_OF_ERROR = 0.1F; // tenth of a millisecond
133

134     // defines if this run will overwrite existing statistics
135
static final boolean UPDATE_STATS = true;
136     
137     // delete this file to reset the previous statistics
138
static final File JavaDoc propFile = new File JavaDoc( "wsifPerformanceStats.txt" );
139     
140     static final int DEFAULT_ITERATIONS = 500;
141     
142     static final boolean TEST_GETPORT = true;
143     static final boolean TEST_CREATEOP = true;
144     static final boolean TEST_EXECOP = true;
145
146     static Properties JavaDoc stats, newStats;
147     
148     static final String JavaDoc wsdlLocation =
149         TestUtilities.getWsdlPath("java\\test\\addressbook\\wsifservice")
150             + "AddressBook.wsdl";
151
152     public SpeedTest(String JavaDoc name) {
153         super(name);
154     }
155
156     public static void main(String JavaDoc[] args) {
157        TestUtilities.startListeners();
158        junit.textui.TestRunner.run (suite());
159        TestUtilities.stopListeners();
160     }
161
162     public static Test suite() {
163         TestSuite suite = new TestSuite("Speed Tests");
164         suite.addTest(new TestSuite(SpeedTest.class) );
165         //suite.addTest(new TestSuite(SpeedTest.class) );
166
//suite.addTest(new TestSuite(SpeedTest.class) );
167
return suite;
168     }
169
170     public void setUp() {
171         TestUtilities.setUpExtensionsAndProviders();
172         newStats = new Properties JavaDoc();
173         Monitor.clear();
174     }
175
176     public void testJava() {
177         doit("JavaPort", "java");
178     }
179 /*
180     public void testJava() {
181         doit("JavaPort", "java");
182     }
183     public void testAxis() {
184         doit("SOAPPort", "axis");
185     }
186     JMS seems to slow for most runs
187     public void testSoapJms() {
188         doit("SOAPJMSPort", "soap");
189     }
190     public void testAxisJms() {
191         doit("SOAPJMSPort", "axis");
192     }
193     public void testNativeJms() {
194         doit("NativeJmsPort", "njms" );
195     }
196     //public void testEJB() {
197     //}
198 */

199
200     private void doit(String JavaDoc portName, String JavaDoc protocol) {
201         int iterations;
202         String JavaDoc testName;
203         String JavaDoc testNamePrefix = protocol + "." + portName;
204
205         if (portName.toUpperCase().indexOf("JMS") != -1
206             && !TestUtilities.areWeTesting("jms"))
207             return;
208
209         TestUtilities.setProviderForProtocol( protocol );
210
211         try {
212             WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
213             WSIFService service = factory.getService(wsdlLocation, null, // serviceNS
214
null, // serviceName
215
"http://wsifservice.addressbook/", // portTypeNS
216
"AddressBook"); // portTypeName
217

218             service.mapType(
219                 new javax.xml.namespace.QName JavaDoc(
220                     "http://wsiftypes.addressbook/",
221                     "address"),
222                 Class.forName("addressbook.wsiftypes.Address"));
223
224             service.mapType(
225                 new javax.xml.namespace.QName JavaDoc(
226                     "http://wsiftypes.addressbook/",
227                     "phone"),
228                 Class.forName("addressbook.wsiftypes.Phone"));
229
230             WSIFPort port = null;
231
232             port = service.getPort(portName);
233             
234             /*
235              * Run iterations of getPort
236              */

237             testName = testNamePrefix + ".getPort";
238             iterations = (TEST_GETPORT)? getIterations( testName ) : 1;
239             System.out.println( "running " + iterations + " " + testName + " iterations..." );
240             for (int i = 0; i < iterations; i++ ) {
241                Monitor.start( testName );
242                port = service.getPort(portName);
243                Monitor.stop( testName );
244             }
245
246             WSIFOperation operation =
247                 port.createOperation("addEntry", "AddEntryWholeNameRequest", null);
248
249             WSIFMessage inputMessage = operation.createInputMessage();
250             WSIFMessage outputMessage = operation.createOutputMessage();
251             WSIFMessage faultMessage = operation.createFaultMessage();
252
253             // Create a name and address to add to the addressbook
254
String JavaDoc nameToAdd = "Chris P. Bacon";
255             Address addressToAdd =
256                 new Address(
257                     1,
258                     "The Waterfront",
259                     "Some City",
260                     "NY",
261                     47907,
262                     new Phone(765, "494", "4900"));
263
264             // Add the name and address to the input message
265
inputMessage.setObjectPart("name", nameToAdd);
266             inputMessage.setObjectPart("address", addressToAdd);
267
268             // Execute the operation, obtaining a flag to indicate its success
269
boolean ok=
270                 operation.executeRequestResponseOperation(
271                     inputMessage,
272                     outputMessage,
273                     faultMessage);
274
275             assertTrue( "failed to add name and address!!", ok );
276
277             /*
278              * Run iterations of createOperation
279              */

280             testName = testNamePrefix + ".createOperation";
281             iterations = (TEST_CREATEOP)? getIterations( testName ) : 1;
282             System.out.println( "running " + iterations + " " + testName + " iterations..." );
283             for (int i = 0; i < iterations; i++ ) {
284                Monitor.start( testName );
285                operation = port.createOperation("getAddressFromName");
286                Monitor.stop( testName );
287             }
288
289             /*
290              * Run iterations of executeRequestResponseOperation
291              */

292             testName = testNamePrefix + ".executeOperation";
293             iterations = (TEST_EXECOP)? getIterations( testName ) : 1;
294             System.out.println( "running " + iterations + " " + testName + " iterations..." );
295             for (int i = 0; i < iterations; i++ ) {
296                operation = port.createOperation("getAddressFromName");
297                inputMessage = operation.createInputMessage();
298                outputMessage = operation.createOutputMessage();
299                faultMessage = operation.createFaultMessage();
300
301                inputMessage.setObjectPart("name", nameToAdd);
302
303                Monitor.start( testName );
304                boolean operationSucceeded =
305                   operation.executeRequestResponseOperation(
306                      inputMessage,
307                      outputMessage,
308                      faultMessage);
309                Monitor.stop( testName );
310                if (!operationSucceeded) {
311                   System.out.println("Failed to lookup name in addressbook");
312                   assertTrue("executing op returned false!!", false);
313                }
314             }
315
316             // make sure it all worked
317
Address addressFound =
318                (Address) outputMessage.getObjectPart("address");
319             assertTrue( "returned address not correct!!",
320                addressToAdd.equals( addressFound) );
321             
322             Monitor.printResults();
323            
324             // test is theres a performance change
325
boolean worse = testResults();
326             setIterations( testNamePrefix );
327             mergeNewStats();
328             if ( UPDATE_STATS ) {
329                saveStatsToFile();
330             }
331
332             assertTrue( "performance is worse than before!!", !worse );
333
334        } catch (Exception JavaDoc ex) {
335            ex.printStackTrace();
336            assertTrue("exception executing op!!", false);
337        }
338     }
339
340     private boolean testResults() {
341         float diff;
342         String JavaDoc s1, s2;
343         boolean worse = false;
344
345         HashMap JavaDoc results = Monitor.getAvgResults();
346         String JavaDoc testName;
347         float duration, oldDuration;
348         for (Iterator JavaDoc i = results.keySet().iterator(); i.hasNext(); ) {
349             testName = (String JavaDoc)i.next();
350             duration = ((Float JavaDoc)results.get( testName )).floatValue();
351             duration = ((float)Math.round( duration * 1000 ) / 1000 );
352             oldDuration = getfloatStat( testName );
353             newStats.setProperty( testName, ""+duration );
354             diff = duration - oldDuration;
355             if ( Math.abs(diff) - MARGIN_OF_ERROR > 0 ) {
356                 worse = diff > 0;
357                 System.err.println( testName + " significantly " +
358                    ( worse? "worse" : "better" ) +
359                    " by " + diff + " msecs, time = " + duration + " msecs" );
360             }
361         }
362
363         return worse;
364     }
365     
366     private int getIterations(String JavaDoc testName) {
367         int i;
368         i = getintStat( testName + ".Iterations" );
369         if ( i == 0 ) {
370             i = DEFAULT_ITERATIONS;
371         }
372         return i;
373     }
374     
375     private void setIterations(String JavaDoc prefix) {
376         String JavaDoc s;
377         int iterations;
378         float duration, createDuration;
379         HashMap JavaDoc results = Monitor.getAvgResults();
380         
381         s = prefix + ".getPort";
382         duration = ((Float JavaDoc)results.get( s )).floatValue();
383         iterations = (duration==0) ?
384            DEFAULT_ITERATIONS : (int)((TIME_PER_TEST*100) / (duration*100));
385         newStats.setProperty( s + ".Iterations", ""+iterations );
386
387         s = prefix + ".createOperation";
388         duration = ((Float JavaDoc)results.get( s )).floatValue();
389         iterations = (duration==0) ?
390            DEFAULT_ITERATIONS : (int)((TIME_PER_TEST*100) / (duration*100));
391         newStats.setProperty( s + ".Iterations", ""+iterations );
392         createDuration = duration;
393
394         s = prefix + ".executeOperation";
395         duration = ((Float JavaDoc)results.get( s )).floatValue();
396         iterations = (duration==0) ?
397            DEFAULT_ITERATIONS : (int)((TIME_PER_TEST*100) / ((duration+createDuration)*100));
398         newStats.setProperty( s + ".Iterations", ""+iterations );
399
400     }
401     
402     private int getintStat(String JavaDoc name) {
403         int i;
404         Properties JavaDoc stats = getStats();
405         try {
406            i = Integer.parseInt(stats.getProperty( name ) );
407         } catch (Exception JavaDoc ex) {
408            i = 0;
409         }
410         return i;
411     }
412     
413     private float getfloatStat(String JavaDoc name) {
414         float f;
415         Properties JavaDoc stats = getStats();
416         try {
417            f = Float.parseFloat(stats.getProperty( name ) );
418         } catch (Exception JavaDoc ex) {
419            f = 0;
420         }
421         return f;
422     }
423     
424     private static Properties JavaDoc getStats() {
425         if ( stats == null ) {
426             loadStatsFromFile();
427         }
428         return stats;
429     }
430
431     private static void mergeNewStats() {
432         Properties JavaDoc stats = getStats();
433         String JavaDoc testName;
434         String JavaDoc value;
435         int iterations;
436         for (Enumeration JavaDoc i = newStats.keys(); i.hasMoreElements(); ) {
437            testName = (String JavaDoc)i.nextElement();
438            value = (String JavaDoc)newStats.get( testName );
439            stats.setProperty( testName, value );
440         }
441     }
442     
443     private static void loadStatsFromFile() {
444         try {
445            FileInputStream JavaDoc fis = new FileInputStream JavaDoc( propFile );
446            stats = new Properties JavaDoc();
447            stats.load( fis );
448         } catch (Exception JavaDoc ex) {
449             stats = new Properties JavaDoc();
450         }
451     }
452     
453     private static void saveStatsToFile() {
454         try {
455            FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc( propFile );
456            stats.store( fos, "WSIF Performance stats" );
457         } catch (Exception JavaDoc ex) {
458             ex.printStackTrace();
459         }
460     }
461         
462 }
Popular Tags