1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.assertNotSame;
25 import static org.junit.jupiter.api.Assertions.assertThrows;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27
28 import java.io.ByteArrayOutputStream;
29 import java.io.OutputStreamWriter;
30 import java.io.PrintStream;
31 import java.io.PrintWriter;
32 import java.nio.charset.StandardCharsets;
33 import java.sql.Connection;
34 import java.sql.DriverManager;
35 import java.sql.SQLException;
36 import java.time.Duration;
37
38 import javax.sql.DataSource;
39
40 import org.apache.commons.pool2.ObjectPool;
41 import org.apache.commons.pool2.impl.GenericObjectPool;
42 import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
43 import org.junit.jupiter.api.AfterEach;
44 import org.junit.jupiter.api.Assertions;
45 import org.junit.jupiter.api.BeforeEach;
46 import org.junit.jupiter.api.Test;
47
48
49
50
51 public class TestPoolingDriver extends TestConnectionPool {
52
53 private PoolingDriver driver;
54
55 @Override
56 protected Connection getConnection() throws Exception {
57 return DriverManager.getConnection("jdbc:apache:commons:dbcp:test");
58 }
59
60 @BeforeEach
61 public void setUp() throws Exception {
62 final DriverConnectionFactory cf = new DriverConnectionFactory(new TesterDriver(), "jdbc:apache:commons:testdriver", null);
63
64 final PoolableConnectionFactory pcf = new PoolableConnectionFactory(cf, null);
65 pcf.setPoolStatements(true);
66 pcf.setMaxOpenPreparedStatements(10);
67 pcf.setValidationQuery("SELECT COUNT(*) FROM DUAL");
68 pcf.setDefaultReadOnly(Boolean.FALSE);
69 pcf.setDefaultAutoCommit(Boolean.TRUE);
70
71 final GenericObjectPoolConfig<PoolableConnection> poolConfig = new GenericObjectPoolConfig<>();
72 poolConfig.setMaxTotal(getMaxTotal());
73 poolConfig.setMaxWait(getMaxWaitDuration());
74 poolConfig.setMinIdle(10);
75 poolConfig.setTestOnBorrow(true);
76 poolConfig.setTestOnReturn(true);
77 poolConfig.setTestWhileIdle(true);
78 poolConfig.setTimeBetweenEvictionRuns(Duration.ofMillis(10_000));
79 poolConfig.setNumTestsPerEvictionRun(5);
80 poolConfig.setMinEvictableIdleTime(Duration.ofMillis(5_000));
81
82 final GenericObjectPool<PoolableConnection> pool = new GenericObjectPool<>(pcf, poolConfig);
83 pcf.setPool(pool);
84
85 assertNotNull(pcf);
86 driver = new PoolingDriver(true);
87 driver.registerPool("test", pool);
88 }
89
90 @Override
91 @AfterEach
92 public void tearDown() throws Exception {
93 driver.closePool("test");
94 super.tearDown();
95 }
96
97 @Test
98 void test1() {
99 final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:some:connect:string", "userName", "password");
100 final PoolableConnectionFactory pcf = new PoolableConnectionFactory(connectionFactory, null);
101 pcf.setDefaultReadOnly(Boolean.FALSE);
102 pcf.setDefaultAutoCommit(Boolean.TRUE);
103 final GenericObjectPool<PoolableConnection> connectionPool = new GenericObjectPool<>(pcf);
104 pcf.setPool(connectionPool);
105 final DataSource ds = new PoolingDataSource<>(connectionPool);
106 Assertions.assertNotNull(ds);
107 }
108
109 @Test
110 void test2() {
111 final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:some:connect:string", "userName", "password");
112 final PoolableConnectionFactory pcf = new PoolableConnectionFactory(connectionFactory, null);
113 pcf.setDefaultReadOnly(Boolean.FALSE);
114 pcf.setDefaultAutoCommit(Boolean.TRUE);
115 final GenericObjectPool<PoolableConnection> connectionPool = new GenericObjectPool<>(pcf);
116 final PoolingDriver driver2 = new PoolingDriver();
117 driver2.registerPool("example", connectionPool);
118 }
119
120 @Test
121 void testClosePool() throws Exception {
122 final Connection conn = DriverManager.getConnection("jdbc:apache:commons:dbcp:test");
123 assertNotNull(conn);
124 conn.close();
125
126 final PoolingDriver driver2 = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
127 driver2.closePool("test");
128
129 assertThrows(SQLException.class, () -> DriverManager.getConnection("jdbc:apache:commons:dbcp:test"));
130 }
131
132 @Test
133 void testInvalidateConnection() throws Exception {
134 final Connection conn = DriverManager.getConnection("jdbc:apache:commons:dbcp:test");
135 assertNotNull(conn);
136
137 final ObjectPool<?> pool = driver.getConnectionPool("test");
138 assertEquals(1, pool.getNumActive());
139 assertEquals(0, pool.getNumIdle());
140
141 final PoolingDriver driver2 = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
142 driver2.invalidateConnection(conn);
143
144 assertEquals(0, pool.getNumActive());
145 assertTrue(conn.isClosed());
146 }
147
148 @Test
149 void testLogWriter() throws Exception {
150 final PrintStream ps = new PrintStream(new ByteArrayOutputStream(), false, StandardCharsets.UTF_8.name());
151 final PrintWriter pw = new PrintWriter(new OutputStreamWriter(new ByteArrayOutputStream(), StandardCharsets.UTF_8));
152 System.setErr(new PrintStream(new ByteArrayOutputStream(), false, StandardCharsets.UTF_8.name()));
153 SQLException ex;
154
155 DriverManager.setLogWriter(pw);
156 ex = new SQLException("A", new Exception("a"));
157 ex.printStackTrace();
158 ex.printStackTrace(ps);
159 ex.printStackTrace(pw);
160 ex = new SQLException("B");
161 ex.printStackTrace();
162 ex.printStackTrace(ps);
163 ex.printStackTrace(pw);
164 ex = new SQLException(null, new Exception("c"));
165 ex.printStackTrace();
166 ex.printStackTrace(ps);
167 ex.printStackTrace(pw);
168 ex = new SQLException((String) null);
169 ex.printStackTrace();
170 ex.printStackTrace(ps);
171 ex.printStackTrace(pw);
172
173 DriverManager.setLogWriter(null);
174 ex = new SQLException("A", new Exception("a"));
175 ex.printStackTrace();
176 ex.printStackTrace(ps);
177 ex.printStackTrace(pw);
178 ex = new SQLException("B");
179 ex.printStackTrace();
180 ex.printStackTrace(ps);
181 ex.printStackTrace(pw);
182 ex = new SQLException(null, new Exception("c"));
183 ex.printStackTrace();
184 ex.printStackTrace(ps);
185 ex.printStackTrace(pw);
186 ex = new SQLException((String) null);
187 ex.printStackTrace();
188 ex.printStackTrace(ps);
189 ex.printStackTrace(pw);
190 }
191
192
193 @Test
194 void testReportedBug12400() throws Exception {
195 final GenericObjectPoolConfig<PoolableConnection> config = new GenericObjectPoolConfig<>();
196 config.setMaxTotal(70);
197 config.setMaxWait(Duration.ofMinutes(1));
198 config.setMaxIdle(10);
199 final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:apache:commons:testdriver", "userName", "password");
200 final PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null);
201 poolableConnectionFactory.setDefaultReadOnly(Boolean.FALSE);
202 poolableConnectionFactory.setDefaultAutoCommit(Boolean.TRUE);
203 final ObjectPool<PoolableConnection> connectionPool = new GenericObjectPool<>(poolableConnectionFactory, config);
204 poolableConnectionFactory.setPool(connectionPool);
205 assertNotNull(poolableConnectionFactory);
206 final PoolingDriver driver2 = new PoolingDriver();
207 driver2.registerPool("neusoftim", connectionPool);
208 final Connection[] conn = new Connection[25];
209 for (int i = 0; i < 25; i++) {
210 conn[i] = DriverManager.getConnection("jdbc:apache:commons:dbcp:neusoftim");
211 for (int j = 0; j < i; j++) {
212 assertNotSame(conn[j], conn[i]);
213 assertNotEquals(conn[j], conn[i]);
214 }
215 }
216 for (int i = 0; i < 25; i++) {
217 conn[i].close();
218 }
219 }
220
221
222 @Test
223 void testReportedBug28912() throws Exception {
224 final Connection conn1 = getConnection();
225 assertNotNull(conn1);
226 assertFalse(conn1.isClosed());
227 conn1.close();
228
229 final Connection conn2 = getConnection();
230 assertNotNull(conn2);
231
232 assertTrue(conn1.isClosed());
233 assertFalse(conn2.isClosed());
234
235
236 conn1.close();
237
238 assertTrue(conn1.isClosed());
239 assertFalse(conn2.isClosed());
240 }
241 }