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.assertNotNull;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  
25  import java.lang.management.ManagementFactory;
26  import java.sql.Connection;
27  import java.time.Duration;
28  import java.util.List;
29  import java.util.Map.Entry;
30  import java.util.Properties;
31  
32  import javax.management.MBeanServer;
33  import javax.naming.Reference;
34  import javax.naming.StringRefAddr;
35  
36  import org.apache.commons.pool2.impl.GenericObjectPool;
37  import org.junit.jupiter.api.Test;
38  
39  /**
40   * TestSuite for BasicDataSourceFactory
41   */
42  public class TestBasicDataSourceFactory {
43  
44      private void checkConnectionPoolProperties(final GenericObjectPool<PoolableConnection> cp) {
45          assertEquals(10, cp.getMaxTotal());
46          assertEquals(8, cp.getMaxIdle());
47          assertEquals(0, cp.getMinIdle());
48          assertEquals(Duration.ofMillis(500), cp.getMaxWaitDuration());
49          assertEquals(5, cp.getNumIdle());
50          assertTrue(cp.getTestOnBorrow());
51          assertFalse(cp.getTestOnReturn());
52          assertEquals(Duration.ofSeconds(1), cp.getDurationBetweenEvictionRuns());
53          assertEquals(Duration.ofSeconds(2), cp.getMinEvictableIdleDuration());
54          assertEquals(Duration.ofSeconds(3), cp.getSoftMinEvictableIdleDuration());
55          assertEquals(2, cp.getNumTestsPerEvictionRun());
56          assertTrue(cp.getTestWhileIdle());
57          assertTrue(cp.getRemoveAbandonedOnBorrow());
58          assertTrue(cp.getRemoveAbandonedOnMaintenance());
59          assertEquals(Duration.ofSeconds(3000), cp.getRemoveAbandonedTimeoutDuration());
60          assertTrue(cp.getLogAbandoned());
61          assertTrue(cp.getLifo());
62      }
63  
64      private void checkDataSourceProperties(final BasicDataSource ds) throws Exception {
65          assertEquals("org.apache.commons.dbcp2.TesterDriver", ds.getDriverClassName());
66          assertEquals("jdbc:apache:commons:testdriver", ds.getUrl());
67          assertEquals(10, ds.getMaxTotal());
68          assertEquals(8, ds.getMaxIdle());
69          assertEquals(0, ds.getMinIdle());
70          assertEquals(Duration.ofMillis(500), ds.getMaxWaitDuration());
71          assertEquals(5, ds.getInitialSize());
72          assertEquals(5, ds.getNumIdle());
73          assertEquals(Boolean.TRUE, ds.getDefaultAutoCommit());
74          assertEquals(Boolean.FALSE, ds.getDefaultReadOnly());
75          assertEquals(Connection.TRANSACTION_READ_COMMITTED, ds.getDefaultTransactionIsolation());
76          assertEquals("test", ds.getDefaultCatalog());
77          assertEquals("testSchema", ds.getDefaultSchema());
78          assertTrue(ds.getTestOnBorrow());
79          assertFalse(ds.getTestOnReturn());
80          assertEquals("userName", ds.getUsername());
81          assertEquals("userName", ds.getUserName());
82          assertEquals("password", ds.getPassword());
83          assertEquals("SELECT DUMMY FROM DUAL", ds.getValidationQuery());
84          assertEquals(Duration.ofSeconds(100), ds.getValidationQueryTimeoutDuration());
85          assertEquals(2, ds.getConnectionInitSqls().size());
86          assertEquals("SELECT 1", ds.getConnectionInitSqls().get(0));
87          assertEquals("SELECT 2", ds.getConnectionInitSqls().get(1));
88          assertEquals(Duration.ofMillis(1000), ds.getDurationBetweenEvictionRuns());
89          assertEquals(Duration.ofMillis(2000), ds.getMinEvictableIdleDuration());
90          assertEquals(Duration.ofMillis(3000), ds.getSoftMinEvictableIdleDuration());
91          assertEquals(2, ds.getNumTestsPerEvictionRun());
92          assertTrue(ds.getTestWhileIdle());
93          assertTrue(ds.isAccessToUnderlyingConnectionAllowed());
94          assertTrue(ds.getRemoveAbandonedOnBorrow());
95          assertTrue(ds.getRemoveAbandonedOnMaintenance());
96          assertEquals(Duration.ofSeconds(3000), ds.getRemoveAbandonedTimeoutDuration());
97          assertTrue(ds.getLogAbandoned());
98          assertTrue(ds.getAbandonedUsageTracking());
99          assertTrue(ds.isPoolPreparedStatements());
100         assertTrue(ds.isClearStatementPoolOnReturn());
101         assertEquals(10, ds.getMaxOpenPreparedStatements());
102         assertTrue(ds.getLifo());
103         assertTrue(ds.getFastFailValidation());
104         assertTrue(ds.getDisconnectionSqlCodes().contains("XXX"));
105         assertTrue(ds.getDisconnectionSqlCodes().contains("YYY"));
106         assertEquals("org.apache.commons.dbcp2:name=test", ds.getJmxName());
107 
108         // Unregister so subsequent calls to getTestProperties can re-register
109         final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
110         mbs.unregisterMBean(ds.getRegisteredJmxName());
111     }
112 
113     private Properties getTestProperties() {
114         final Properties properties = new Properties();
115         properties.setProperty("driverClassName", "org.apache.commons.dbcp2.TesterDriver");
116         properties.setProperty("url", "jdbc:apache:commons:testdriver");
117         properties.setProperty("maxTotal", "10");
118         properties.setProperty("maxIdle", "8");
119         properties.setProperty("minIdle", "0");
120         properties.setProperty("maxWaitMillis", "500");
121         properties.setProperty("initialSize", "5");
122         properties.setProperty("defaultAutoCommit", "true");
123         properties.setProperty("defaultReadOnly", "false");
124         properties.setProperty("defaultTransactionIsolation", "READ_COMMITTED");
125         properties.setProperty("defaultCatalog", "test");
126         properties.setProperty("defaultSchema", "testSchema");
127         properties.setProperty("testOnBorrow", "true");
128         properties.setProperty("testOnReturn", "false");
129         properties.setProperty("username", "userName");
130         properties.setProperty("password", "password");
131         properties.setProperty("validationQuery", "SELECT DUMMY FROM DUAL");
132         properties.setProperty("validationQueryTimeout", "100");
133         properties.setProperty("connectionInitSqls", "SELECT 1;SELECT 2");
134         properties.setProperty("timeBetweenEvictionRunsMillis", "1000");
135         properties.setProperty("minEvictableIdleTimeMillis", "2000");
136         properties.setProperty("softMinEvictableIdleTimeMillis", "3000");
137         properties.setProperty("numTestsPerEvictionRun", "2");
138         properties.setProperty("testWhileIdle", "true");
139         properties.setProperty("accessToUnderlyingConnectionAllowed", "true");
140         properties.setProperty("removeAbandonedOnBorrow", "true");
141         properties.setProperty("removeAbandonedOnMaintenance", "true");
142         properties.setProperty("removeAbandonedTimeout", "3000");
143         properties.setProperty("logAbandoned", "true");
144         properties.setProperty("abandonedUsageTracking", "true");
145         properties.setProperty("poolPreparedStatements", "true");
146         properties.setProperty("clearStatementPoolOnReturn", "true");
147         properties.setProperty("maxOpenPreparedStatements", "10");
148         properties.setProperty("lifo", "true");
149         properties.setProperty("fastFailValidation", "true");
150         properties.setProperty("disconnectionSqlCodes", "XXX,YYY");
151         properties.setProperty("jmxName", "org.apache.commons.dbcp2:name=test");
152         return properties;
153     }
154 
155     @Test
156     public void testAllProperties() throws Exception {
157         try {
158             StackMessageLog.lock();
159             StackMessageLog.clear();
160             final Reference ref = new Reference("javax.sql.DataSource", BasicDataSourceFactory.class.getName(), null);
161             final Properties properties = getTestProperties();
162             for (final Entry<Object, Object> entry : properties.entrySet()) {
163                 ref.add(new StringRefAddr((String) entry.getKey(), (String) entry.getValue()));
164             }
165             final BasicDataSourceFactory basicDataSourceFactory = new BasicDataSourceFactory();
166             try (final BasicDataSource ds = (BasicDataSource) basicDataSourceFactory.getObjectInstance(ref, null, null, null)) {
167                 checkDataSourceProperties(ds);
168                 checkConnectionPoolProperties(ds.getConnectionPool());
169                 final List<String> messages = StackMessageLog.getAll();
170                 assertEquals(0, messages.size());
171             }
172         } finally {
173             StackMessageLog.clear();
174             StackMessageLog.unLock();
175         }
176     }
177 
178     @Test
179     public void testNoProperties() throws Exception {
180         final Properties properties = new Properties();
181         try (final BasicDataSource ds = BasicDataSourceFactory.createDataSource(properties)) {
182             assertNotNull(ds);
183         }
184     }
185 
186     @Test
187     public void testProperties() throws Exception {
188         try (final BasicDataSource ds = BasicDataSourceFactory.createDataSource(getTestProperties())) {
189             checkDataSourceProperties(ds);
190         }
191     }
192 
193     @Test
194     public void testValidateProperties() throws Exception {
195         try {
196             StackMessageLog.lock();
197             StackMessageLog.clear();
198             final Reference ref = new Reference("javax.sql.DataSource", BasicDataSourceFactory.class.getName(), null);
199             ref.add(new StringRefAddr("foo", "bar")); // Unknown
200             ref.add(new StringRefAddr("maxWait", "100")); // Changed
201             ref.add(new StringRefAddr("driverClassName", "org.apache.commons.dbcp2.TesterDriver")); // OK
202             final BasicDataSourceFactory basicDataSourceFactory = new BasicDataSourceFactory();
203             basicDataSourceFactory.getObjectInstance(ref, null, null, null);
204             final List<String> messages = StackMessageLog.getAll();
205             assertEquals(2, messages.size(), messages.toString());
206             for (final String message : messages) {
207                 if (message.contains("maxWait")) {
208                     assertTrue(message.contains("use maxWaitMillis"));
209                 } else {
210                     assertTrue(message.contains("foo"));
211                     assertTrue(message.contains("Ignoring unknown property"));
212                 }
213             }
214         } finally {
215             StackMessageLog.clear();
216             StackMessageLog.unLock();
217         }
218     }
219 }