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;
19  
20  import static org.junit.jupiter.api.Assertions.assertThrows;
21  import static org.junit.jupiter.api.Assertions.fail;
22  
23  import java.sql.Connection;
24  import java.sql.SQLException;
25  import java.util.Properties;
26  
27  import javax.sql.DataSource;
28  
29  import org.apache.commons.pool2.impl.GenericObjectPool;
30  import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
31  import org.junit.jupiter.api.Test;
32  
33  /**
34   * This test *must* execute before all other tests to be effective as it tests the initialization of DriverManager. Based on the test case for DBCP-212 written
35   * by Marcos Sanz
36   */
37  public class TestDriverManagerConnectionFactory extends AbstractDriverTest {
38  
39      private static final class ConnectionThread implements Runnable {
40          private final DataSource ds;
41          private volatile boolean result = true;
42  
43          private ConnectionThread(final DataSource ds) {
44              this.ds = ds;
45          }
46  
47          public boolean getResult() {
48              return result;
49          }
50  
51          @Override
52          public void run() {
53              Connection conn = null;
54              try {
55                  conn = ds.getConnection();
56              } catch (final Exception e) {
57                  e.printStackTrace();
58                  result = false;
59              } finally {
60                  if (conn != null) {
61                      try {
62                          conn.close();
63                      } catch (final Exception e) {
64                          e.printStackTrace();
65                          result = false;
66                      }
67                  }
68              }
69          }
70  
71          @Override
72          public String toString() {
73              return "ConnectionThread [ds=" + ds + ", result=" + result + "]";
74          }
75      }
76  
77      @Test
78      void testDriverManagerCredentialsInUrl() throws SQLException {
79          final DriverManagerConnectionFactory cf = new DriverManagerConnectionFactory("jdbc:apache:commons:testdriver;user=foo;password=bar", null,
80                  (char[]) null);
81          cf.createConnection();
82      }
83  
84      void testDriverManagerInit(final boolean withProperties) throws Exception {
85          final GenericObjectPoolConfig<PoolableConnection> config = new GenericObjectPoolConfig<>();
86          config.setMaxTotal(10);
87          config.setMaxIdle(0);
88          final Properties properties = new Properties();
89          // The names "user" and "password" are specified in
90          // java.sql.DriverManager.getConnection(String, String, String)
91          properties.setProperty(Constants.KEY_USER, "foo");
92          properties.setProperty(Constants.KEY_PASSWORD, "bar");
93          final ConnectionFactory connectionFactory = withProperties ? new DriverManagerConnectionFactory("jdbc:apache:commons:testdriver", properties)
94                  : new DriverManagerConnectionFactory("jdbc:apache:commons:testdriver", "foo", "bar");
95          final PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null);
96          poolableConnectionFactory.setDefaultReadOnly(Boolean.FALSE);
97          poolableConnectionFactory.setDefaultAutoCommit(Boolean.TRUE);
98  
99          final GenericObjectPool<PoolableConnection> connectionPool = new GenericObjectPool<>(poolableConnectionFactory, config);
100         poolableConnectionFactory.setPool(connectionPool);
101         final PoolingDataSource<PoolableConnection> dataSource = new PoolingDataSource<>(connectionPool);
102 
103         final ConnectionThread[] connectionThreads = new ConnectionThread[10];
104         final Thread[] threads = new Thread[10];
105 
106         for (int i = 0; i < 10; i++) {
107             connectionThreads[i] = new ConnectionThread(dataSource);
108             threads[i] = new Thread(connectionThreads[i]);
109         }
110         for (int i = 0; i < 10; i++) {
111             threads[i].start();
112         }
113         for (int i = 0; i < 10; i++) {
114             while (threads[i].isAlive()) { // JDK1.5: getState() != Thread.State.TERMINATED) {
115                 Thread.sleep(100);
116             }
117             if (!connectionThreads[i].getResult()) {
118                 fail("Exception during getConnection(): " + connectionThreads[i]);
119             }
120         }
121     }
122 
123     @Test
124     void testDriverManagerInitWithCredentials() throws Exception {
125         testDriverManagerInit(false);
126     }
127 
128     @Test
129     void testDriverManagerInitWithEmptyProperties() throws Exception {
130         final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:apache:commons:testdriver;user=foo;password=bar");
131         connectionFactory.createConnection();
132     }
133 
134     @Test
135     void testDriverManagerInitWithProperties() throws Exception {
136         testDriverManagerInit(true);
137     }
138 
139     @Test
140     void testDriverManagerWithoutCredentials() {
141         final DriverManagerConnectionFactory cf = new DriverManagerConnectionFactory("jdbc:apache:commons:testdriver", null, (char[]) null);
142         assertThrows(ArrayIndexOutOfBoundsException.class, cf::createConnection); // thrown by TestDriver due to missing user
143     }
144 
145     @Test
146     void testDriverManagerWithoutPassword() {
147         final DriverManagerConnectionFactory cf = new DriverManagerConnectionFactory("jdbc:apache:commons:testdriver", "user", (char[]) null);
148         assertThrows(SQLException.class, cf::createConnection); // thrown by TestDriver due to invalid password
149     }
150 
151     @Test
152     void testDriverManagerWithoutUser() {
153         final DriverManagerConnectionFactory cf = new DriverManagerConnectionFactory("jdbc:apache:commons:testdriver", null, "pass");
154         assertThrows(IndexOutOfBoundsException.class, cf::createConnection); // thrown by TestDriver due to missing user
155     }
156 
157 }