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    *      https://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.datasources;
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.assertNotNull;
23  import static org.junit.jupiter.api.Assertions.assertNull;
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.io.PrintWriter;
29  import java.sql.Connection;
30  import java.sql.SQLException;
31  import java.time.Duration;
32  import java.util.Properties;
33  
34  import org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS;
35  import org.junit.jupiter.api.AfterEach;
36  import org.junit.jupiter.api.BeforeEach;
37  import org.junit.jupiter.api.Test;
38  
39  /**
40   */
41  public class TestInstanceKeyDataSource {
42  
43      private static final class ThrowOnSetupDefaultsDataSource extends SharedPoolDataSource {
44  
45          private static final long serialVersionUID = -448025812063133259L;
46  
47          ThrowOnSetupDefaultsDataSource() {
48          }
49  
50          @Override
51          protected void setupDefaults(final Connection connection, final String userName) throws SQLException {
52              throw new SQLException("bang!");
53          }
54      }
55  
56      private static final String DRIVER = "org.apache.commons.dbcp2.TesterDriver";
57      private static final String URL = "jdbc:apache:commons:testdriver";
58      private static final String USER = "foo";
59      private static final String PASS = "bar";
60  
61      private DriverAdapterCPDS pcds;
62      private SharedPoolDataSource spds;
63  
64      @BeforeEach
65      public void setUp() throws ClassNotFoundException {
66          pcds = new DriverAdapterCPDS();
67          pcds.setDriver(DRIVER);
68          pcds.setUrl(URL);
69          pcds.setUser(USER);
70          pcds.setPassword(PASS);
71          pcds.setPoolPreparedStatements(false);
72          spds = new SharedPoolDataSource();
73          spds.setConnectionPoolDataSource(pcds);
74      }
75  
76      @AfterEach
77      public void tearDown() throws Exception {
78          spds.close();
79      }
80  
81      @Test
82      void testConnection() throws SQLException, ClassNotFoundException {
83          spds = new SharedPoolDataSource();
84          pcds.setDriver(DRIVER);
85          pcds.setUrl(URL);
86          spds.setConnectionPoolDataSource(pcds);
87          final PooledConnectionAndInfo info = spds.getPooledConnectionAndInfo(null, null);
88          assertNull(info.getUserName());
89          assertNull(info.getPassword());
90          try (final Connection conn = spds.getConnection()) {
91              assertNotNull(conn);
92          }
93      }
94  
95      @Test
96      void testConnectionPoolDataSource() {
97          assertEquals(pcds, spds.getConnectionPoolDataSource());
98      }
99  
100     @Test
101     void testConnectionPoolDataSourceAlreadySet() {
102         assertThrows(IllegalStateException.class, () -> spds.setConnectionPoolDataSource(new DriverAdapterCPDS()));
103     }
104 
105     @Test
106     void testConnectionPoolDataSourceAlreadySetUsingJndi() {
107         spds = new SharedPoolDataSource();
108         spds.setDataSourceName("anything");
109         assertThrows(IllegalStateException.class, () -> spds.setConnectionPoolDataSource(new DriverAdapterCPDS()));
110     }
111 
112     @Test
113     void testDataSourceName() {
114         spds = new SharedPoolDataSource();
115         assertNull(spds.getDataSourceName());
116         spds.setDataSourceName("anything");
117         assertEquals("anything", spds.getDataSourceName());
118     }
119 
120     @Test
121     void testDataSourceNameAlreadySet() {
122         assertThrows(IllegalStateException.class, () -> spds.setDataSourceName("anything"));
123     }
124 
125     @Test
126     void testDataSourceNameAlreadySetUsingJndi() {
127         spds = new SharedPoolDataSource();
128         spds.setDataSourceName("anything");
129         assertThrows(IllegalStateException.class, () -> spds.setDataSourceName("anything"));
130     }
131 
132     @Test
133     void testDefaultBlockWhenExhausted() {
134         spds.setDefaultBlockWhenExhausted(true);
135         assertTrue(spds.getDefaultBlockWhenExhausted());
136         spds.setDefaultBlockWhenExhausted(false);
137         assertFalse(spds.getDefaultBlockWhenExhausted());
138     }
139 
140     @Test
141     void testDefaultEvictionPolicyClassName() {
142         spds.setDefaultEvictionPolicyClassName(Object.class.getName());
143         assertEquals(Object.class.getName(), spds.getDefaultEvictionPolicyClassName());
144     }
145 
146     @Test
147     void testDefaultLifo() {
148         spds.setDefaultLifo(true);
149         assertTrue(spds.getDefaultLifo());
150         spds.setDefaultLifo(false);
151         assertFalse(spds.getDefaultLifo());
152     }
153 
154     @Test
155     void testDefaultMinIdle() {
156         spds.setDefaultMinIdle(10);
157         assertEquals(10, spds.getDefaultMinIdle());
158     }
159 
160     @Test
161     void testDefaultReadOnly() {
162         spds.setDefaultReadOnly(true);
163         assertTrue(spds.isDefaultReadOnly());
164         spds.setDefaultReadOnly(false);
165         assertFalse(spds.isDefaultReadOnly());
166     }
167 
168     @Test
169     void testDefaultSoftMinEvictableIdleTimeMillis() {
170         spds.setDefaultSoftMinEvictableIdleTimeMillis(10);
171         assertEquals(10, spds.getDefaultSoftMinEvictableIdleTimeMillis());
172     }
173 
174     @Test
175     void testDefaultTestOnCreate() {
176         spds.setDefaultTestOnCreate(false);
177         assertFalse(spds.getDefaultTestOnCreate());
178         spds.setDefaultTestOnCreate(true);
179         assertTrue(spds.getDefaultTestOnCreate());
180     }
181 
182     @Test
183     void testDefaultTransactionIsolation() {
184         assertEquals(InstanceKeyDataSource.UNKNOWN_TRANSACTIONISOLATION, spds.getDefaultTransactionIsolation());
185         spds.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
186         assertEquals(Connection.TRANSACTION_READ_COMMITTED, spds.getDefaultTransactionIsolation());
187     }
188 
189     @Test
190     void testDefaultTransactionIsolationInvalid() {
191         assertEquals(InstanceKeyDataSource.UNKNOWN_TRANSACTIONISOLATION, spds.getDefaultTransactionIsolation());
192         assertThrows(IllegalArgumentException.class, () -> spds.setDefaultTransactionIsolation(Integer.MAX_VALUE));
193     }
194 
195     @Test
196     void testDescription() {
197         spds.setDescription("anything");
198         assertEquals("anything", spds.getDescription());
199     }
200 
201     /**
202      * Verify that exception on setupDefaults does not leak PooledConnection
203      *
204      * JIRA: DBCP-237
205      * @throws Exception
206      */
207     @Test
208     void testExceptionOnSetupDefaults() throws Exception {
209         try (final ThrowOnSetupDefaultsDataSource tds = new ThrowOnSetupDefaultsDataSource()) {
210             final int numConnections = tds.getNumActive();
211             assertThrows(SQLException.class, () -> tds.getConnection(USER, PASS));
212             assertEquals(numConnections, tds.getNumActive());
213         }
214     }
215 
216     @Test
217     void testIsWrapperFor() throws Exception {
218         assertTrue(spds.isWrapperFor(InstanceKeyDataSource.class));
219         assertTrue(spds.isWrapperFor(AutoCloseable.class));
220     }
221 
222     @Test
223     void testJndiEnvironment() {
224         assertNull(spds.getJndiEnvironment("name"));
225         final Properties properties = new Properties();
226         properties.setProperty("name", "clarke");
227         spds.setJndiEnvironment(properties);
228         assertEquals("clarke", spds.getJndiEnvironment("name"));
229         spds.setJndiEnvironment("name", "asimov");
230         assertEquals("asimov", spds.getJndiEnvironment("name"));
231     }
232 
233     @Test
234     void testJndiNullProperties() {
235         assertThrows(NullPointerException.class, () -> spds.setJndiEnvironment(null));
236     }
237 
238     @Test
239     void testJndiPropertiesCleared() {
240         spds.setJndiEnvironment("name", "king");
241         assertEquals("king", spds.getJndiEnvironment("name"));
242         final Properties properties = new Properties();
243         properties.setProperty("fish", "kohi");
244         spds.setJndiEnvironment(properties);
245         assertNull(spds.getJndiEnvironment("name"));
246     }
247 
248     @Test
249     void testJndiPropertiesNotInitialized() {
250         assertNull(spds.getJndiEnvironment("name"));
251         spds.setJndiEnvironment("name", "king");
252         assertEquals("king", spds.getJndiEnvironment("name"));
253     }
254 
255     @Test
256     void testLoginTimeout() {
257         spds.setLoginTimeout(10);
258         assertEquals(10, spds.getLoginTimeout());
259     }
260 
261     @SuppressWarnings("resource")
262     @Test
263     void testLogWriter() {
264         spds.setLogWriter(new PrintWriter(System.out));
265         assertNotNull(spds.getLogWriter());
266     }
267 
268     @SuppressWarnings("resource")
269     @Test
270     void testLogWriterAutoInitialized() {
271         assertNotNull(spds.getLogWriter());
272     }
273 
274     @Test
275     void testMaxConnLifetimeMillis() {
276         assertEquals(-1, spds.getMaxConnLifetimeMillis());
277         spds.setMaxConnLifetimeMillis(10);
278         assertEquals(10, spds.getMaxConnLifetimeMillis());
279     }
280 
281     @Test
282     void testRollbackAfterValidation() {
283         assertFalse(spds.isRollbackAfterValidation());
284         spds.setRollbackAfterValidation(true);
285         assertTrue(spds.isRollbackAfterValidation());
286     }
287 
288     @Test
289     void testRollbackAfterValidationWithConnectionCalled() throws SQLException {
290         try (Connection connection = spds.getConnection()) {
291             assertFalse(spds.isRollbackAfterValidation());
292             assertThrows(IllegalStateException.class, () -> spds.setRollbackAfterValidation(true));
293         }
294     }
295 
296     @SuppressWarnings("resource")
297     @Test
298     void testUnwrap() throws Exception {
299         assertSame(spds.unwrap(InstanceKeyDataSource.class), spds);
300         assertSame(spds.unwrap(AutoCloseable.class), spds);
301     }
302 
303     @Test
304     void testValidationQuery() {
305         assertNull(spds.getValidationQuery());
306         spds.setValidationQuery("anything");
307         assertEquals("anything", spds.getValidationQuery());
308     }
309 
310     @Test
311     void testValidationQueryTimeout() {
312         assertEquals(-1, spds.getValidationQueryTimeout());
313         spds.setValidationQueryTimeout(10);
314         assertEquals(10, spds.getValidationQueryTimeout());
315     }
316 
317     @Test
318     void testValidationQueryTimeoutDuration() {
319         assertEquals(Duration.ofSeconds(-1), spds.getValidationQueryTimeoutDuration());
320         spds.setValidationQueryTimeout(Duration.ofSeconds(10));
321         assertEquals(Duration.ofSeconds(10), spds.getValidationQueryTimeoutDuration());
322     }
323 
324     @Test
325     void testValidationQueryWithConnectionCalled() throws SQLException {
326         try (Connection connection = spds.getConnection()) {
327             assertNull(spds.getValidationQuery());
328             assertThrows(IllegalStateException.class, () -> spds.setValidationQuery("anything"));
329         }
330     }
331 }