View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.dbcp2;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertNotEquals;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertSame;
25  import static org.junit.jupiter.api.Assertions.assertThrows;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  
28  import java.sql.Connection;
29  import java.sql.SQLException;
30  import java.util.Properties;
31  
32  import org.apache.commons.pool2.impl.GenericObjectPool;
33  import org.junit.jupiter.api.AfterEach;
34  import org.junit.jupiter.api.Assertions;
35  import org.junit.jupiter.api.BeforeEach;
36  import org.junit.jupiter.api.Test;
37  
38  /**
39   * TestSuite for PoolingDataSource
40   */
41  public class TestPoolingDataSource extends TestConnectionPool {
42  
43      protected PoolingDataSource<PoolableConnection> ds;
44  
45      private GenericObjectPool<PoolableConnection> pool;
46      @Override
47      protected Connection getConnection() throws Exception {
48          return ds.getConnection();
49      }
50  
51      @BeforeEach
52      public void setUp() throws Exception {
53          final Properties properties = new Properties();
54          properties.setProperty(Constants.KEY_USER, "userName");
55          properties.setProperty(Constants.KEY_PASSWORD, "password");
56          final PoolableConnectionFactory factory =
57              new PoolableConnectionFactory(
58                      new DriverConnectionFactory(new TesterDriver(),
59                              "jdbc:apache:commons:testdriver", properties),
60                      null);
61          factory.setValidationQuery("SELECT DUMMY FROM DUAL");
62          factory.setDefaultReadOnly(Boolean.TRUE);
63          factory.setDefaultAutoCommit(Boolean.TRUE);
64          pool = new GenericObjectPool<>(factory);
65          factory.setPool(pool);
66          pool.setMaxTotal(getMaxTotal());
67          pool.setMaxWait(getMaxWaitDuration());
68          ds = new PoolingDataSource<>(pool);
69          ds.setAccessToUnderlyingConnectionAllowed(true);
70      }
71  
72      @Override
73      @AfterEach
74      public void tearDown() throws Exception {
75          ds.close();
76          super.tearDown();
77      }
78  
79      @Test
80      public void testClose() throws Exception {
81  
82          final Properties properties = new Properties();
83          properties.setProperty(Constants.KEY_USER, "userName");
84          properties.setProperty(Constants.KEY_PASSWORD, "password");
85          final PoolableConnectionFactory f =
86              new PoolableConnectionFactory(
87                      new DriverConnectionFactory(new TesterDriver(),
88                              "jdbc:apache:commons:testdriver", properties),
89                      null);
90          f.setValidationQuery("SELECT DUMMY FROM DUAL");
91          f.setDefaultReadOnly(Boolean.TRUE);
92          f.setDefaultAutoCommit(Boolean.TRUE);
93          final GenericObjectPool<PoolableConnection> p = new GenericObjectPool<>(f);
94          p.setMaxTotal(getMaxTotal());
95          p.setMaxWait(getMaxWaitDuration());
96  
97          try ( PoolingDataSource<PoolableConnection> dataSource = new PoolingDataSource<>(p) ) {
98              final Connection connection = dataSource.getConnection();
99              assertNotNull(connection);
100             connection.close();
101         }
102 
103         assertTrue(p.isClosed());
104         assertEquals(0, p.getNumIdle());
105         assertEquals(0, p.getNumActive());
106     }
107 
108     /**
109      * DBCP-412
110      * Verify that omitting factory.setPool(pool) when setting up PDS does not
111      * result in NPE.
112      */
113     @Test
114     public void testFixFactoryConfig() throws Exception {
115         final Properties properties = new Properties();
116         properties.setProperty(Constants.KEY_USER, "userName");
117         properties.setProperty(Constants.KEY_PASSWORD, "password");
118         final PoolableConnectionFactory f =
119             new PoolableConnectionFactory(
120                     new DriverConnectionFactory(new TesterDriver(),
121                             "jdbc:apache:commons:testdriver", properties),
122                     null);
123         f.setValidationQuery("SELECT DUMMY FROM DUAL");
124         f.setDefaultReadOnly(Boolean.TRUE);
125         f.setDefaultAutoCommit(Boolean.TRUE);
126         final GenericObjectPool<PoolableConnection> p = new GenericObjectPool<>(f);
127         p.setMaxTotal(getMaxTotal());
128         p.setMaxWait(getMaxWaitDuration());
129         ds = new PoolingDataSource<>(p);
130         assertEquals(f.getPool(), p);
131         ds.getConnection();
132     }
133 
134     @Test
135     public void testIsWrapperFor() throws Exception {
136         assertTrue(ds.isWrapperFor(PoolingDataSource.class));
137         assertTrue(ds.isWrapperFor(AutoCloseable.class));
138         assertFalse(ds.isWrapperFor(String.class));
139         assertFalse(ds.isWrapperFor(null));
140     }
141 
142     @Test
143     public void testPoolGuardConnectionWrapperEqualInnermost() throws Exception {
144         ds.setAccessToUnderlyingConnectionAllowed(true);
145         final DelegatingConnection<?> con = (DelegatingConnection<?>) ds.getConnection();
146         final Connection inner = con.getInnermostDelegate();
147         ds.setAccessToUnderlyingConnectionAllowed(false);
148         final DelegatingConnection<Connection> con2 = new DelegatingConnection<>(inner);
149         assertNotEquals(con2, con);
150         assertTrue(con.innermostDelegateEquals(con2.getInnermostDelegate()));
151         assertTrue(con2.innermostDelegateEquals(inner));
152         assertNotEquals(con, con2);
153     }
154 
155     @Test
156     public void testPoolGuardConnectionWrapperEqualsFail() throws Exception {
157         final Connection con1 = ds.getConnection();
158         final Connection con2 = ds.getConnection();
159         assertNotEquals(con1, con2);
160         con1.close();
161         con2.close();
162     }
163 
164     @Test
165     public void testPoolGuardConnectionWrapperEqualsNull() throws Exception {
166         final Connection con1 = ds.getConnection();
167         final Connection con2 = null;
168         assertNotEquals(con2, con1);
169         con1.close();
170     }
171 
172     /*
173      * JIRA: DBCP-198
174      */
175     @Test
176     public void testPoolGuardConnectionWrapperEqualsReflexive()
177         throws Exception {
178         final Connection con = ds.getConnection();
179         final Connection con2 = con;
180         assertEquals(con2, con);
181         assertEquals(con, con2);
182         con.close();
183     }
184 
185     @Test
186     public void testPoolGuardConnectionWrapperEqualsSameDelegate() throws Exception {
187         // Get a maximal set of connections from the pool
188         final Connection[] c = new Connection[getMaxTotal()];
189         for (int i = 0; i < c.length; i++) {
190             c[i] = newConnection();
191         }
192         // Close the delegate of one wrapper in the pool
193         ((DelegatingConnection<?>) c[0]).getDelegate().close();
194 
195         // Grab a new connection - should get c[0]'s closed connection
196         // so should be delegate-equivalent
197         final Connection con = newConnection();
198         Assertions.assertNotEquals(c[0], con);
199         Assertions.assertEquals(
200                 ((DelegatingConnection<?>) c[0]).getInnermostDelegateInternal(),
201                 ((DelegatingConnection<?>) con).getInnermostDelegateInternal());
202         for (final Connection element : c) {
203             element.close();
204         }
205     }
206 
207     @Test
208     public void testPoolGuardConnectionWrapperEqualsType() throws Exception {
209         final Connection con1 = ds.getConnection();
210         final Integer con2 = 0;
211         assertNotEquals(con2, con1);
212         con1.close();
213     }
214 
215     @Test
216     public void testUnwrap() throws Exception {
217         assertSame(ds.unwrap(PoolingDataSource.class), ds);
218         assertSame(ds.unwrap(AutoCloseable.class), ds);
219         assertThrows(SQLException.class, () -> ds.unwrap(String.class));
220         assertThrows(SQLException.class, () -> ds.unwrap(null));
221     }
222 }