1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.assertNotEquals;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25
26 import java.sql.Connection;
27 import java.sql.SQLException;
28 import java.time.Duration;
29
30 import javax.sql.PooledConnection;
31
32 import org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS;
33 import org.apache.commons.pool2.impl.GenericObjectPool;
34 import org.junit.jupiter.api.BeforeEach;
35 import org.junit.jupiter.api.Test;
36
37
38
39 public class TestCPDSConnectionFactory {
40
41 protected ConnectionPoolDataSourceProxy cpds;
42
43 private void checkPoolLimits(final GenericObjectPool<PooledConnectionAndInfo> pool) {
44 assertTrue(pool.getNumActive() + pool.getNumIdle() <= pool.getMaxTotal(),
45 "Active + Idle should be <= MaxTotal");
46 assertTrue(pool.getNumIdle() <= pool.getMaxIdle(), "Idle should be <= MaxIdle");
47 }
48
49 @BeforeEach
50 public void setUp() throws Exception {
51 cpds = new ConnectionPoolDataSourceProxy(new DriverAdapterCPDS());
52 final DriverAdapterCPDS delegate = (DriverAdapterCPDS) cpds.getDelegate();
53 delegate.setDriver("org.apache.commons.dbcp2.TesterDriver");
54 delegate.setUrl("jdbc:apache:commons:testdriver");
55 delegate.setUser("userName");
56 delegate.setPassword("password");
57 }
58
59
60
61
62
63
64
65 @Test
66 void testConnectionErrorCleanup() throws Exception {
67
68 final CPDSConnectionFactory factory = new CPDSConnectionFactory(cpds, null, Duration.ofMillis(-1), false, "userName", "password".toCharArray());
69 try (final GenericObjectPool<PooledConnectionAndInfo> pool = new GenericObjectPool<>(factory)) {
70 factory.setPool(pool);
71
72
73 final PooledConnection pcon1 = pool.borrowObject().getPooledConnection();
74 try (final Connection con1 = pcon1.getConnection()) {
75 final PooledConnection pcon2 = pool.borrowObject().getPooledConnection();
76 assertEquals(2, pool.getNumActive());
77 assertEquals(0, pool.getNumIdle());
78
79
80 final PooledConnectionProxy pc = (PooledConnectionProxy) pcon1;
81 assertTrue(pc.getListeners().contains(factory));
82
83
84 pc.throwConnectionError();
85
86
87 assertEquals(1, pool.getNumActive());
88 checkPoolLimits(pool);
89
90
91 pc.throwConnectionError();
92 assertEquals(1, pool.getNumActive());
93 checkPoolLimits(pool);
94
95
96 final PooledConnection pcon3 = pool.borrowObject().getPooledConnection();
97 assertNotEquals(pcon3, pcon1);
98 assertFalse(pc.getListeners().contains(factory));
99 assertEquals(2, pool.getNumActive());
100 assertEquals(0, pool.getNumIdle());
101
102
103 pcon2.getConnection().close();
104 pcon3.getConnection().close();
105 assertEquals(2, pool.getNumIdle());
106 assertEquals(0, pool.getNumActive());
107
108
109 assertThrows(SQLException.class, pc::getConnection, "Expecting SQLException using closed PooledConnection");
110
111
112 con1.close();
113 assertEquals(2, pool.getNumIdle());
114 assertEquals(0, pool.getNumActive());
115
116
117 pool.clear();
118 assertEquals(0, pool.getNumIdle());
119 }
120 }
121 }
122
123
124
125
126 @Test
127 void testNullValidationQuery() throws Exception {
128 final CPDSConnectionFactory factory = new CPDSConnectionFactory(cpds, null, Duration.ofMillis(-1), false, "userName", "password".toCharArray());
129 try (final GenericObjectPool<PooledConnectionAndInfo> pool = new GenericObjectPool<>(factory)) {
130 factory.setPool(pool);
131 pool.setTestOnBorrow(true);
132 final PooledConnection pcon = pool.borrowObject().getPooledConnection();
133 try (final Connection con = pcon.getConnection()) {
134 }
135 }
136 }
137
138 @Test
139 void testSetPasswordCharArray() {
140 final CPDSConnectionFactory factory = new CPDSConnectionFactory(cpds, null, Duration.ofMillis(-1), false, "userName", "password".toCharArray());
141 final char[] pwd = { 'a' };
142 factory.setPassword(pwd);
143 assertEquals("a", String.valueOf(factory.getPasswordCharArray()));
144 pwd[0] = 'b';
145 assertEquals("a", String.valueOf(factory.getPasswordCharArray()));
146 }
147
148 @Test
149 void testSetPasswordString() {
150 final CPDSConnectionFactory factory = new CPDSConnectionFactory(cpds, null, Duration.ofMillis(-1), false, "userName", "password".toCharArray());
151 final String pwd = "a";
152 factory.setPassword(pwd);
153 assertEquals("a", String.valueOf(factory.getPasswordCharArray()));
154 }
155
156
157
158
159
160
161
162
163 @Test
164 void testSharedPoolDSDestroyOnReturn() throws Exception {
165 try (final PerUserPoolDataSource ds = new PerUserPoolDataSource()) {
166 ds.setConnectionPoolDataSource(cpds);
167 ds.setPerUserMaxTotal("userName", 10);
168 ds.setPerUserMaxWait("userName", Duration.ofMillis(50));
169 ds.setPerUserMaxIdle("userName", 2);
170 final Connection conn1 = ds.getConnection("userName", "password");
171 final Connection conn2 = ds.getConnection("userName", "password");
172 final Connection conn3 = ds.getConnection("userName", "password");
173 assertEquals(3, ds.getNumActive("userName"));
174 conn1.close();
175 assertEquals(1, ds.getNumIdle("userName"));
176 conn2.close();
177 assertEquals(2, ds.getNumIdle("userName"));
178 conn3.close();
179 assertEquals(2, ds.getNumIdle("userName"));
180 }
181 }
182
183 }