KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opensubsystems > core > persist > db > connectionpool > PooledDatabaseConnectionFactoryImplBaseTest


1 /*
2  * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
3  *
4  * Project: OpenSubsystems
5  *
6  * $Id: PooledDatabaseConnectionFactoryImplBaseTest.java,v 1.4 2007/01/07 06:14:20 bastafidli Exp $
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21
22 package org.opensubsystems.core.persist.db.connectionpool;
23
24 import java.sql.Connection JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Properties JavaDoc;
28 import java.util.logging.Level JavaDoc;
29 import java.util.logging.Logger JavaDoc;
30
31 import org.opensubsystems.core.error.OSSDatabaseAccessException;
32 import org.opensubsystems.core.error.OSSException;
33 import org.opensubsystems.core.error.OSSInternalErrorException;
34 import org.opensubsystems.core.util.Config;
35 import org.opensubsystems.core.util.GlobalConstants;
36 import org.opensubsystems.core.util.Log;
37
38 /**
39  * Base class containing tests for general concepts of pooled database connection
40  * factories, which every pooled database connection factory should support.
41  *
42  * @version $Id: PooledDatabaseConnectionFactoryImplBaseTest.java,v 1.4 2007/01/07 06:14:20 bastafidli Exp $
43  * @author Julian Legeny
44  * @code.reviewer Miro Halas
45  * @code.reviewed 1.14 2004/10/05 07:39:53 bastafidli
46  */

47 public abstract class PooledDatabaseConnectionFactoryImplBaseTest extends
48                          DatabaseConnectionFactoryBaseTest
49 {
50    // Constants/////////////////////////////////////////////////////////////////
51

52    /**
53     * Constant defining MAX POOL SIZE - maximal number of connections in the pool
54     */

55    protected static final int ALL_CONNECTION_COUNT = 5;
56    
57    /**
58     * Constant defining POOL WAIT PERIOD - how long the pool will be waiting when
59     * there are used all connections in the pool. Time is specified in miliseconds
60     * c3p0 is executing lots of operations asynchronously and if this is too low
61     * (e.g. 2000) you may get message that it cannto acquire connection even
62     * though connection is available. Solution is to keep this high enough.
63     */

64    protected static final int POOL_WAIT_PERIOD = 5000;
65  
66    // Cached variables /////////////////////////////////////////////////////////
67

68    /**
69     * Logger for this class
70     */

71    private static Logger JavaDoc s_logger = Log.getInstance(
72                                        PooledDatabaseConnectionFactoryImplBaseTest.class);
73    
74    // Constructors /////////////////////////////////////////////////////////////
75

76    /**
77     * Create new PooledDatabaseConnectionFactoryImplBaseTest.
78     *
79     * @param strTestName - name of the test
80     */

81    public PooledDatabaseConnectionFactoryImplBaseTest(
82       String JavaDoc strTestName
83    )
84    {
85       super(strTestName);
86    }
87
88    // Tests ////////////////////////////////////////////////////////////////////
89

90    /**
91     * Set up environment for the test case.
92     *
93     * @throws Exception - an error has occured during setting up test
94     */

95    protected void setUp(
96    ) throws Exception JavaDoc
97    {
98       String JavaDoc strTestName;
99
100       // set actual test name
101
strTestName = getName();
102
103       // get properties and predefine particular values
104
Properties JavaDoc predefinedProperties = Config.getInstance().getProperties();
105
106       // construct property name for MIN POOL SIZE
107
String JavaDoc strMinPoolSize = PooledDatabaseConnectionFactorySetupReader.DATABASE_POOL_BASE_PATH +
108                                "." + DATASOURCE_NAME_1 + "." +
109                                PooledDatabaseConnectionFactorySetupReader.DBPOOL_MIN_SIZE;
110       // set minimal size for connection pool
111
// We have to allocate min count less then the max count since in the method
112
// testRequestConnectionByUserAndPassword we allocate connection using different user
113
// name and password and it fails to do it
114
// TODO: Bug: XAPool 1.4.1: Once XAPool fixes it behaviour consider setting
115
// it back to MAX_SIZE
116
predefinedProperties.put(strMinPoolSize, Integer.toString(ALL_CONNECTION_COUNT - 1));
117
118       // construct property name for INIT POOL SIZE
119
String JavaDoc strInitPoolSize = PooledDatabaseConnectionFactorySetupReader.DATABASE_POOL_BASE_PATH +
120                                "." + DATASOURCE_NAME_1 + "." +
121                                PooledDatabaseConnectionFactorySetupReader.DBPOOL_INITIAL_SIZE;
122       // set initial size for connection pool
123
predefinedProperties.put(strInitPoolSize, (new Integer JavaDoc(ALL_CONNECTION_COUNT)).toString());
124
125       // construct property name for MAX POOL SIZE
126
String JavaDoc strMaxPoolSize = PooledDatabaseConnectionFactorySetupReader.DATABASE_POOL_BASE_PATH +
127                                "." + DATASOURCE_NAME_1 + "." +
128                                PooledDatabaseConnectionFactorySetupReader.DBPOOL_MAX_SIZE;
129       // set maximal size for connection pool
130
predefinedProperties.put(strMaxPoolSize, (new Integer JavaDoc(ALL_CONNECTION_COUNT)).toString());
131
132       // construct property name for POOL WAIT PERIOD
133
String JavaDoc strWaitPeriod = PooledDatabaseConnectionFactorySetupReader.DATABASE_POOL_BASE_PATH +
134                                "." + DATASOURCE_NAME_1 + "." +
135                                PooledDatabaseConnectionFactorySetupReader.DBPOOL_WAIT_PERIOD;
136       // set wait period for pool
137
predefinedProperties.put(strWaitPeriod, (new Integer JavaDoc(POOL_WAIT_PERIOD)).toString());
138
139       // construct property name for CAN GROW
140
String JavaDoc strCanGrow = PooledDatabaseConnectionFactorySetupReader.DATABASE_POOL_BASE_PATH +
141                                "." + DATASOURCE_NAME_1 + "." +
142                                PooledDatabaseConnectionFactorySetupReader.DBPOOL_CAN_GROW;
143
144
145       // set CAN GROW flag - it depends on particular test
146
if (strTestName.equals("testRequestOneMoreCannotGrow"))
147       {
148          predefinedProperties.put(strCanGrow, GlobalConstants.INTEGER_0.toString());
149       }
150       if (strTestName.equals("testRequestOneMoreCanGrow"))
151       {
152          predefinedProperties.put(strCanGrow, GlobalConstants.INTEGER_1.toString());
153       }
154
155       Config.setInstance(new Config(predefinedProperties));
156
157       super.setUp();
158    }
159
160    /**
161     * Test if I configure the factory to return at most X connections and block
162     * then I cannot retrieve more.
163     *
164     * @throws Exception - an error has occured during test
165     */

166    public void testRequestXReturnX(
167    ) throws Exception JavaDoc
168    {
169       Connection JavaDoc con = null;
170       int iIndex;
171       List JavaDoc lstConIdentifiers = new ArrayList JavaDoc(ALL_CONNECTION_COUNT);
172       List JavaDoc lstConnections = new ArrayList JavaDoc(ALL_CONNECTION_COUNT);
173
174       try
175       {
176          for (iIndex = 0; iIndex < ALL_CONNECTION_COUNT; iIndex++)
177          {
178             // request connection
179
// Request autocommit true since we are just reading data from the database
180
con = m_connectionFactory.requestConnection(true);
181             
182             // We need to keep the connection so that the next iteration forces
183
// the pool to return us new connection. We will return them all in
184
// finally
185
lstConnections.add(con);
186
187             // Test if just requested connection is in list.
188
assertFalse("The pool should NOT return existing connection again" +
189                        " since it wasn't returned yet.",
190                        containsConnection(lstConIdentifiers, con));
191
192             // Add connection identifier it to the list, it will be used for testing
193
// if the connection is really pooled and can be requested again
194
lstConIdentifiers.add(addItem(con));
195          }
196       }
197       finally
198       {
199          for (iIndex = 0; (iIndex < ALL_CONNECTION_COUNT)
200              && (!lstConnections.isEmpty()); iIndex++)
201          {
202             // Return connection, we still remember it but it is already returned
203
m_connectionFactory.returnConnection(
204                 (Connection JavaDoc)lstConnections.remove(0));
205          }
206       }
207       
208       assertTrue("Not all connections were returned.", lstConnections.isEmpty());
209
210       // At this point we have stored identifiers for all connections that we
211
// already requested and returned. Now we will request all connections
212
// again and test if they are the same as are stored in the list.
213
try
214       {
215          for (iIndex = 0; iIndex < ALL_CONNECTION_COUNT; iIndex++)
216          {
217             // request connection
218
// Request autocommit true since we are just reading data from the database
219
con = m_connectionFactory.requestConnection(true);
220          
221             // We need to keep the connection so that the next iteration forces
222
// the pool to return us new connection. We will return them all in
223
// finally
224
lstConnections.add(con);
225
226             // Test if just requested connection is in list.
227
assertTrue("The pool should return existing connection again" +
228                        " since it should be pooled.",
229                        containsConnection(lstConIdentifiers, con));
230          }
231       }
232       finally
233       {
234          for (iIndex = 0; (iIndex < ALL_CONNECTION_COUNT)
235              && (!lstConnections.isEmpty()); iIndex++)
236          {
237             // Return connection, we still remember it but it is already returned
238
m_connectionFactory.returnConnection(
239                 (Connection JavaDoc)lstConnections.remove(0));
240          }
241       }
242       
243       assertTrue("Not all connections were returned.", lstConnections.isEmpty());
244    }
245
246    /**
247     * Test for request X+1 connections when there is not possible to grow pool
248     * (CAN GROW flag = FALSE or particular pool doesn't support it).
249     * This method is the same as testRequestOneMoreCanGrow() but we need to have
250     * two methods with different names because we need to set different value
251     * for CAN GROW property.
252     *
253     * @throws Exception - an error has occured during test
254     */

255    public void testRequestOneMoreCannotGrow(
256    ) throws Exception JavaDoc
257    {
258       requestOneMore(false);
259    }
260    
261    /**
262     * Test for request X+1 connections when there is possible to grow pool
263     * (CAN GROW flag = TRUE or particular pool supports it)
264     * This method is the same as testRequestOneMoreCannotGrow() but we need to have
265     * two methods with different names because we need to set different value
266     * for CAN GROW property.
267     *
268     * @throws Exception - an error has occured during test
269     */

270    public void testRequestOneMoreCanGrow(
271    ) throws Exception JavaDoc
272    {
273       requestOneMore(true);
274    }
275
276    /**
277     * Method results if new connection is contained within the list of
278     * first time requested connections.
279     *
280     * @param lstConnections - list of first time requested connections
281     * @param newConnection - just new requested connection (requested second time)
282     *
283     * @return true - if newConnection is contained in the list
284     * false - if newConnection is not contained in the list
285     *
286     * @throws OSSException - exception occured during comparing 2 connections
287     */

288    protected abstract boolean containsConnection(
289       List JavaDoc lstConnections,
290       Connection JavaDoc newConnection
291    ) throws OSSException;
292    
293    // Helper methods ////////////////////////////////////////////////////////////////
294

295    /**
296     * Test for request X+1 connections when there is not possible to grow pool
297     * (can grow flag = false or particular pool doesn't support it)
298     *
299     * @param bCanGrow - can the pool grow
300     * @throws Exception - an error has occured during test
301     */

302    private void requestOneMore(
303       boolean bCanGrow
304    ) throws Exception JavaDoc
305    {
306       Connection JavaDoc con = null;
307       List JavaDoc lstConnections = new ArrayList JavaDoc(ALL_CONNECTION_COUNT);
308
309       try
310       {
311          int iIndex;
312          
313          // Request maximal number of connection in the pool
314
for (iIndex = 0; iIndex < ALL_CONNECTION_COUNT; iIndex++)
315          {
316             // Request autocommit true since we are just reading data from the database
317
con = m_connectionFactory.requestConnection(true);
318
319             // add connection it to the list, it will be used for returning these connections
320
lstConnections.add(con);
321          }
322
323          // At this point we have requested maximal connections in the pool.
324
// Now we try to request one more connection (MAX + 1).
325
Connection JavaDoc cOneMoreConnection = null;
326          long startTime = 0;
327          long endTime = 0;
328    
329          try
330          {
331             // At this point we have requested maximal connections in the pool.
332
// Now we try to request one more connection (MAX + 1).
333
try
334             {
335                startTime = System.currentTimeMillis();
336                // Request autocommit true since we are just reading data from the database
337
cOneMoreConnection = m_connectionFactory.requestConnection(true);
338    
339                if (bCanGrow)
340                {
341                   assertNotNull("Either the pool doesn't implement growing beyond maximal size" +
342                                 " or it failed to grow.", cOneMoreConnection);
343                }
344                else
345                {
346                   // If pool cannot grow, it should throw an exception but never null
347
fail("Pool is setup to do not grow so another connections" +
348                        " shouldn't be returned.");
349                }
350             }
351             catch (OSSDatabaseAccessException daeExc)
352             {
353                if (!bCanGrow)
354                {
355                   // If the pool cannot grow it is expected that it can throw
356
// an exception
357
// If the pool cannot grow it should wait
358
// how long does pool wait
359
endTime = System.currentTimeMillis() - startTime;
360                   
361                   assertTrue("Either the pool doesn't implement pool waiting period" +
362                              " when exhausted or the pool waited less that expected." +
363                              " Expected wait = " + POOL_WAIT_PERIOD + " and waited = "
364                              + endTime, endTime >= POOL_WAIT_PERIOD);
365                }
366                else
367                {
368                   s_logger.log(Level.WARNING,
369                                "Either the pool doesn't implement growing beyond maximal" +
370                                " size or failed to grow.", daeExc);
371                   fail("Either the pool doesn't implement growing beyond maximal" +
372                        " size or it failed to grow.");
373                }
374             }
375          }
376          finally
377          {
378             m_connectionFactory.returnConnection(cOneMoreConnection);
379          }
380       }
381       finally
382       {
383          int iIndex;
384          
385          for (iIndex = 0; (iIndex < ALL_CONNECTION_COUNT)
386              && (!lstConnections.isEmpty()); iIndex++)
387          {
388             // Return connection, we still remember it but it is already returned
389
m_connectionFactory.returnConnection(
390                 (Connection JavaDoc)lstConnections.remove(0));
391          }
392       }
393       
394       assertTrue("Not all connections were returned.", lstConnections.isEmpty());
395    }
396
397    /**
398     * Method returns item that will be added to the list. The item should
399     * uniquely represent the connection or the underlying connection so that
400     * it can be compared with different connections.
401     *
402     * @param cActualConnection - actual connection
403     * @throws OSSInternalErrorException - an error has occured
404     * @return Object - object that will be added to the list
405     */

406    protected Object JavaDoc addItem(
407       Connection JavaDoc cActualConnection
408    ) throws OSSInternalErrorException
409    {
410       return cActualConnection;
411    }
412 }
413
Popular Tags