KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > logicalcobwebs > proxool > PerformanceTest


1 /*
2  * This software is released under a licence similar to the Apache Software Licence.
3  * See org.logicalcobwebs.proxool.package.html for details.
4  * The latest version is available at http://proxool.sourceforge.net
5  */

6 package org.logicalcobwebs.proxool;
7
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10 import org.logicalcobwebs.proxool.admin.StatisticsIF;
11 import org.logicalcobwebs.proxool.admin.StatisticsListenerIF;
12 import org.logicalcobwebs.proxool.admin.SnapshotIF;
13
14 import java.sql.Connection JavaDoc;
15 import java.sql.DriverManager JavaDoc;
16 import java.sql.SQLException JavaDoc;
17 import java.sql.Statement JavaDoc;
18 import java.util.Properties JavaDoc;
19 import java.text.DecimalFormat JavaDoc;
20
21 /**
22  * Tests how fast Proxool is compared to the "perfect" pool, {@link SimpoolAdapter}.
23  *
24  * @version $Revision: 1.18 $, $Date: 2006/01/18 14:40:06 $
25  * @author Bill Horsman (bill@logicalcobwebs.co.uk)
26  * @author $Author: billhorsman $ (current maintainer)
27  * @since Proxool 0.5
28  */

29 public class PerformanceTest extends AbstractProxoolTest implements StatisticsListenerIF {
30
31     private static final Log LOG = LogFactory.getLog(PerformanceTest.class);
32
33     private static DecimalFormat JavaDoc millisecondsFormat = new DecimalFormat JavaDoc("0.00");
34
35     private Thread JavaDoc waitingThead;
36
37     private StatisticsIF statistics;
38     private static final int PERIOD = 5;
39     private static final int COUNT = 6;
40     private long servedCount;
41
42     public PerformanceTest(String JavaDoc s) {
43         super(s);
44     }
45
46     /**
47      * Test how many connections we can serve if we go as fast as we can!
48      * @throws ProxoolException if anything goes wrong
49      */

50     public void testPerformance() throws ProxoolException, InterruptedException JavaDoc {
51
52         waitingThead = Thread.currentThread();
53
54         String JavaDoc alias = "testPeformance";
55         int threadCount = 20;
56         String JavaDoc url = TestHelper.buildProxoolUrl(alias,
57                 TestConstants.HYPERSONIC_DRIVER,
58                 TestConstants.HYPERSONIC_TEST_URL);
59         Properties JavaDoc info = new Properties JavaDoc();
60         info.setProperty(ProxoolConstants.USER_PROPERTY, TestConstants.HYPERSONIC_USER);
61         info.setProperty(ProxoolConstants.PASSWORD_PROPERTY, TestConstants.HYPERSONIC_PASSWORD);
62         info.setProperty(ProxoolConstants.MINIMUM_CONNECTION_COUNT_PROPERTY, String.valueOf(threadCount));
63         info.setProperty(ProxoolConstants.VERBOSE_PROPERTY, String.valueOf(Boolean.TRUE));
64         info.setProperty(ProxoolConstants.MAXIMUM_CONNECTION_COUNT_PROPERTY, String.valueOf(threadCount));
65 /*
66         info.setProperty(ProxoolConstants.STATISTICS_PROPERTY, String.valueOf(PERIOD) + "s");
67         info.setProperty(ProxoolConstants.STATISTICS_LOG_LEVEL_PROPERTY, ProxoolConstants.STATISTICS_LOG_LEVEL_INFO);
68 */

69         ProxoolFacade.registerConnectionPool(url, info);
70 /*
71         ProxoolFacade.addStatisticsListener(alias, this);
72 */

73
74         doWait();
75
76         AnnoyingConnector[] annoyingConnectors = new AnnoyingConnector[threadCount];
77         for (int i = 0; i < annoyingConnectors.length; i++) {
78             annoyingConnectors[i] = new AnnoyingConnector(alias);
79             Thread JavaDoc t = new Thread JavaDoc(annoyingConnectors[i]);
80             t.start();
81         }
82
83         for (int i = 0; i < COUNT; i++) {
84             doWait();
85         }
86
87         for (int i = 0; i < annoyingConnectors.length; i++) {
88             annoyingConnectors[i].cancel();
89         }
90
91         for (int i = 0; i < 5; i++) {
92             int activeConnectionCount = ProxoolFacade.getSnapshot(alias).getActiveConnectionCount();
93             if (activeConnectionCount > 0) {
94                 LOG.info("Waiting for 10 seconds for connections to become inactive (" + activeConnectionCount + ")");
95                 Thread.sleep(10000);
96             } else {
97                 break;
98             }
99         }
100
101         final SnapshotIF snapshot = ProxoolFacade.getSnapshot(alias, true);
102         LOG.info("Active count: " + snapshot.getActiveConnectionCount());
103         LOG.info("Available count: " + snapshot.getAvailableConnectionCount());
104         ConnectionInfoIF[] cis = snapshot.getConnectionInfos();
105         LOG.info("Found " + cis.length + " connetions with a detailed snapshot" + "");
106         for (int i = 0; i < cis.length; i++) {
107             ConnectionInfoIF ci = cis[i];
108             LOG.info("#" + ci.getId() + ": " + ci.getStatus() + ", lap=" + (ci.getTimeLastStopActive() - ci.getTimeLastStartActive()));
109         }
110         LOG.info("Served a total of " + ProxoolFacade.getSnapshot(alias).getServedCount());
111
112     }
113
114     private void doWait() {
115         synchronized (Thread.currentThread()) {
116             try {
117                 Thread.currentThread().wait(60000);
118             } catch (InterruptedException JavaDoc e) {
119                 fail("Statistics didn't arrive as expected");
120             }
121         }
122     }
123
124     public void statistics(String JavaDoc alias, StatisticsIF statistics) {
125         this.servedCount += statistics.getServedCount();
126         this.statistics = statistics;
127         synchronized (waitingThead) {
128             waitingThead.notify();
129         }
130     }
131
132     public void testSnapshotImpact() throws ProxoolException {
133
134         waitingThead = Thread.currentThread();
135
136         String JavaDoc alias = "testPeformance";
137         int threadCount = 10;
138         String JavaDoc url = TestHelper.buildProxoolUrl(alias,
139                 TestConstants.HYPERSONIC_DRIVER,
140                 TestConstants.HYPERSONIC_TEST_URL);
141         Properties JavaDoc info = new Properties JavaDoc();
142         info.setProperty(ProxoolConstants.USER_PROPERTY, TestConstants.HYPERSONIC_USER);
143         info.setProperty(ProxoolConstants.PASSWORD_PROPERTY, TestConstants.HYPERSONIC_PASSWORD);
144         info.setProperty(ProxoolConstants.MINIMUM_CONNECTION_COUNT_PROPERTY, String.valueOf(threadCount));
145         info.setProperty(ProxoolConstants.MAXIMUM_CONNECTION_COUNT_PROPERTY, String.valueOf(threadCount));
146         info.setProperty(ProxoolConstants.STATISTICS_PROPERTY, String.valueOf(PERIOD) + "s");
147         info.setProperty(ProxoolConstants.STATISTICS_LOG_LEVEL_PROPERTY, ProxoolConstants.STATISTICS_LOG_LEVEL_INFO);
148         info.setProperty(ProxoolConstants.VERBOSE_PROPERTY, String.valueOf(Boolean.TRUE));
149         ProxoolFacade.registerConnectionPool(url, info);
150         ProxoolFacade.addStatisticsListener(alias, this);
151         DisagreeableSnapshotter disagreeableSnapshotter = new DisagreeableSnapshotter(alias);
152         new Thread JavaDoc(disagreeableSnapshotter).start();
153
154         AnnoyingConnector[] annoyingConnectors = new AnnoyingConnector[threadCount];
155         for (int i = 0; i < annoyingConnectors.length; i++) {
156             annoyingConnectors[i] = new AnnoyingConnector(alias);
157             Thread JavaDoc t = new Thread JavaDoc(annoyingConnectors[i]);
158             t.start();
159         }
160
161         doWait();
162
163         int servedCount = 0;
164         for (int i = 0; i < COUNT; i++) {
165             doWait();
166             servedCount += statistics.getServedCount();
167             assertTrue("disparityNoticed", !disagreeableSnapshotter.isDisparityNoticed());
168         }
169
170         for (int i = 0; i < annoyingConnectors.length; i++) {
171             annoyingConnectors[i].cancel();
172         }
173         disagreeableSnapshotter.cancel();
174
175         long start = System.currentTimeMillis();
176         while (System.currentTimeMillis() - start < 30000) {
177             int threadsRunning = 0;
178             for (int i = 0; i < annoyingConnectors.length; i++) {
179                 if (annoyingConnectors[i].isRunning()) {
180                     threadsRunning++;
181                 }
182             }
183             if (disagreeableSnapshotter.isRunning()) {
184                 threadsRunning++;
185             }
186             if (threadsRunning == 0) {
187                 break;
188             }
189         }
190
191
192         assertTrue("disparityNoticed", !disagreeableSnapshotter.isDisparityNoticed());
193
194         LOG.info("Served " + servedCount
195             + " at " + millisecondsFormat.format((double) (1000 * PERIOD * COUNT) / (double) servedCount) + " ms per connection");
196
197     }
198
199     class DisagreeableSnapshotter implements Runnable JavaDoc {
200
201         private String JavaDoc alias;
202
203         private boolean cancelled;
204
205         private boolean disparityNoticed;
206
207         private boolean running;
208
209         public DisagreeableSnapshotter(String JavaDoc alias) {
210             this.alias = alias;
211         }
212
213         public void run() {
214
215             running = true;
216             int snapshotCount = 0;
217             while (!cancelled) {
218                 try {
219                     Thread.sleep(100);
220                 } catch (InterruptedException JavaDoc e) {
221                     LOG.error("Awoken", e);
222                 }
223                 try {
224                     SnapshotIF s = ProxoolFacade.getSnapshot(alias, true);
225                     int c1 = s.getActiveConnectionCount();
226                     int c2 = getCount(s.getConnectionInfos(), ConnectionInfoIF.STATUS_ACTIVE);
227                     int v1 = s.getAvailableConnectionCount();
228                     int v2 = getCount(s.getConnectionInfos(), ConnectionInfoIF.STATUS_AVAILABLE);
229                     int o1 = s.getOfflineConnectionCount();
230                     int o2 = getCount(s.getConnectionInfos(), ConnectionInfoIF.STATUS_OFFLINE);
231                     if (c1 != c2 || v1 != v2 || o1 != o2) {
232                         LOG.error("Disparity noticed. Active: " + c1 + (c1 == c2 ? " == " : " != ") + c2
233                             + ", available: " + v1 + (v1 == v2 ? " == " : " != ") + v2
234                             + ", offline: " + o1 + (o1 == o2 ? " == " : " != ") + o2);
235                         disparityNoticed = true;
236                     }
237                     snapshotCount++;
238                 } catch (ProxoolException e) {
239                     LOG.error("Couldn't get snapshot", e);
240                 }
241             }
242             LOG.info(snapshotCount + " snapshots taken");
243             running = false;
244         }
245
246         public boolean isRunning() {
247             return running;
248         }
249
250         private int getCount(ConnectionInfoIF[] connectionInfos, int status) {
251             int count = 0;
252             for (int i = 0; i < connectionInfos.length; i++) {
253                 if (connectionInfos[i].getStatus() == status) {
254                     count++;
255                 }
256             }
257             return count;
258         }
259
260         public boolean isDisparityNoticed() {
261             return disparityNoticed;
262         }
263
264         public void cancel() {
265             cancelled = true;
266         }
267
268     }
269
270     class AnnoyingConnector implements Runnable JavaDoc {
271
272         private String JavaDoc alias;
273
274         private boolean cancelled;
275
276         private int exceptionCount;
277
278         private boolean running = false;
279
280         public AnnoyingConnector(String JavaDoc alias) {
281             this.alias = alias;
282         }
283
284         public void run() {
285             running = true;
286                 while (!cancelled) {
287                     try {
288                         Connection JavaDoc connection = null;
289                         Statement JavaDoc s = null;
290                         try {
291                             connection = DriverManager.getConnection(TestHelper.buildProxoolUrl(alias));
292                             s = connection.createStatement();
293                             Thread.yield();
294                         } finally {
295                             if (s != null) {
296                                 s.close();
297                             }
298                             if (connection != null) {
299                                 connection.close();
300                             }
301                         }
302                     } catch (SQLException JavaDoc e) {
303                         LOG.error(Thread.currentThread().getName(), e);
304                         exceptionCount++;
305                     }
306                 }
307             running = false;
308         }
309
310         public boolean isRunning() {
311             return running;
312         }
313
314         public void cancel() {
315             cancelled = true;
316         }
317
318         public int getExceptionCount() {
319             return exceptionCount;
320         }
321
322     }
323
324 }
325
326 /*
327  Revision history:
328  $Log: PerformanceTest.java,v $
329  Revision 1.18 2006/01/18 14:40:06 billhorsman
330  Unbundled Jakarta's Commons Logging.
331
332  Revision 1.17 2003/11/04 13:54:02 billhorsman
333  checkstyle
334
335  Revision 1.16 2003/03/11 14:58:32 billhorsman
336  put PerformanceTest back in the global test
337
338  Revision 1.15 2003/03/11 14:51:43 billhorsman
339  more concurrency fixes relating to snapshots
340
341  Revision 1.14 2003/03/10 23:49:04 billhorsman
342  new test to measure the impact of taking snapshots
343
344  Revision 1.13 2003/03/10 15:31:26 billhorsman
345  fixes
346
347  Revision 1.12 2003/03/04 10:24:40 billhorsman
348  removed try blocks around each test
349
350  Revision 1.11 2003/03/03 17:08:57 billhorsman
351  all tests now extend AbstractProxoolTest
352
353  Revision 1.10 2003/03/03 11:12:04 billhorsman
354  fixed licence
355
356  Revision 1.9 2003/03/01 15:27:24 billhorsman
357  checkstyle
358
359  Revision 1.8 2003/02/19 15:14:23 billhorsman
360  fixed copyright (copy and paste error,
361  not copyright change)
362
363  Revision 1.7 2003/02/06 17:41:03 billhorsman
364  now uses imported logging
365
366  Revision 1.6 2002/12/16 17:05:05 billhorsman
367  new test structure
368
369  Revision 1.5 2002/11/09 16:01:53 billhorsman
370  fix doc
371
372  Revision 1.4 2002/11/02 14:22:16 billhorsman
373  Documentation
374
375  Revision 1.3 2002/11/02 13:57:34 billhorsman
376  checkstyle
377
378  Revision 1.2 2002/11/02 11:37:48 billhorsman
379  New tests
380
381  Revision 1.1 2002/10/30 21:17:51 billhorsman
382  new performance tests
383
384 */

385
Popular Tags