1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.dbcp2.managed;
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.assertSame;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26 import static org.junit.jupiter.api.Assertions.fail;
27
28 import java.sql.CallableStatement;
29 import java.sql.Connection;
30 import java.sql.PreparedStatement;
31 import java.sql.ResultSet;
32 import java.sql.SQLException;
33 import java.sql.Statement;
34
35 import javax.transaction.Synchronization;
36 import javax.transaction.Transaction;
37
38 import org.apache.commons.dbcp2.DelegatingConnection;
39 import org.junit.jupiter.api.AfterEach;
40 import org.junit.jupiter.api.Assertions;
41 import org.junit.jupiter.api.BeforeEach;
42 import org.junit.jupiter.api.Test;
43
44
45
46
47 public class TestManagedDataSourceInTx extends TestManagedDataSource {
48
49
50 @Override
51 protected void assertBackPointers(final Connection conn, final Statement statement) throws SQLException {
52 assertFalse(conn.isClosed());
53 assertFalse(isClosed(statement));
54
55 assertSame(conn, statement.getConnection(),
56 "statement.getConnection() should return the exact same connection instance that was used to create the statement");
57
58 try (ResultSet resultSet = statement.getResultSet()) {
59 assertFalse(isClosed(resultSet));
60 assertSame(statement, resultSet.getStatement(),
61 "resultSet.getStatement() should return the exact same statement instance that was used to create the result set");
62
63 try (ResultSet executeResultSet = statement.executeQuery("select * from dual")) {
64 assertFalse(isClosed(executeResultSet));
65 assertSame(statement, executeResultSet.getStatement(),
66 "resultSet.getStatement() should return the exact same statement instance that was used to create the result set");
67 }
68
69 try (ResultSet keysResultSet = statement.getGeneratedKeys()) {
70 assertFalse(isClosed(keysResultSet));
71 assertSame(statement, keysResultSet.getStatement(),
72 "resultSet.getStatement() should return the exact same statement instance that was used to create the result set");
73 }
74 if (statement instanceof PreparedStatement) {
75 final PreparedStatement preparedStatement = (PreparedStatement) statement;
76 try (ResultSet preparedResultSet = preparedStatement.executeQuery()) {
77 assertFalse(isClosed(preparedResultSet));
78 assertSame(statement, preparedResultSet.getStatement(),
79 "resultSet.getStatement() should return the exact same statement instance that was used to create the result set");
80 }
81 }
82
83 resultSet.getStatement().getConnection().close();
84 }
85 }
86
87 @Override
88 @BeforeEach
89 public void setUp() throws Exception {
90 super.setUp();
91 transactionManager.begin();
92 }
93
94 @Override
95 @AfterEach
96 public void tearDown() throws Exception {
97 if (transactionManager.getTransaction() != null) {
98 transactionManager.commit();
99 }
100 super.tearDown();
101 }
102
103 @Override
104 @Test
105 public void testAutoCommitBehavior() throws Exception {
106 final Connection connection = newConnection();
107
108
109 assertFalse(connection.getAutoCommit(), "Auto-commit should be disabled");
110
111
112 try {
113 connection.setAutoCommit(true);
114 fail("setAutoCommit method should be disabled while enlisted in a transaction");
115 } catch (final SQLException e) {
116
117 }
118
119
120 assertFalse(connection.getAutoCommit(), "Auto-commit should be disabled");
121
122
123 connection.close();
124 }
125
126 @Override
127 @Test
128 public void testClearWarnings() throws Exception {
129
130 Connection connection = newConnection();
131 assertNotNull(connection);
132
133
134 final CallableStatement statement = connection.prepareCall("warning");
135 assertNotNull(connection.getWarnings());
136
137
138 final Connection sharedConnection = newConnection();
139
140
141 assertNotNull(sharedConnection.getWarnings());
142
143
144 connection.close();
145 connection = newConnection();
146
147
148 assertNotNull(connection.getWarnings());
149 assertNotNull(sharedConnection.getWarnings());
150
151 statement.close();
152 sharedConnection.close();
153 connection.close();
154 }
155
156 @Test
157 public void testCloseInTransaction() throws Exception {
158 try (DelegatingConnection<?> connectionA = (DelegatingConnection<?>) newConnection();
159 DelegatingConnection<?> connectionB = (DelegatingConnection<?>) newConnection()) {
160 assertNotEquals(connectionA, connectionB);
161 assertNotEquals(connectionB, connectionA);
162 assertTrue(connectionA.innermostDelegateEquals(connectionB.getInnermostDelegate()));
163 assertTrue(connectionB.innermostDelegateEquals(connectionA.getInnermostDelegate()));
164 }
165
166 final Connection connection = newConnection();
167
168 assertFalse(connection.isClosed(), "Connection should be open");
169
170 connection.close();
171
172 assertTrue(connection.isClosed(), "Connection should be closed");
173 }
174
175 @Test
176 public void testCommit() throws Exception {
177 try (Connection connection = newConnection()) {
178
179
180 assertFalse(connection.isClosed(), "Connection should be open");
181
182
183 try {
184 connection.commit();
185 fail("commit method should be disabled while enlisted in a transaction");
186 } catch (final SQLException e) {
187
188 }
189
190
191 assertFalse(connection.isClosed(), "Connection should be open");
192
193 }
194 }
195
196 @Override
197 @Test
198 public void testConnectionReturnOnCommit() throws Exception {
199
200 }
201
202 @Override
203 @Test
204 public void testConnectionsAreDistinct() throws Exception {
205 final Connection[] conn = new Connection[getMaxTotal()];
206 for (int i = 0; i < conn.length; i++) {
207 conn[i] = newConnection();
208 for (int j = 0; j < i; j++) {
209
210 Assertions.assertNotSame(conn[j], conn[i]);
211
212
213 Assertions.assertNotEquals(conn[j], conn[i]);
214
215 Assertions.assertEquals(((DelegatingConnection<?>) conn[j]).getInnermostDelegateInternal(),
216 ((DelegatingConnection<?>) conn[i]).getInnermostDelegateInternal());
217 }
218 }
219 for (final Connection element : conn) {
220 element.close();
221 }
222 }
223
224 @Test
225 public void testDoubleReturn() throws Exception {
226 transactionManager.getTransaction().registerSynchronization(new Synchronization() {
227 private ManagedConnection<?> conn;
228
229 @Override
230 public void afterCompletion(final int i) {
231 final int numActive = pool.getNumActive();
232 try {
233 conn.checkOpen();
234 } catch (final Exception e) {
235
236 }
237 assertEquals(numActive, pool.getNumActive());
238 try {
239 conn.close();
240 } catch (final Exception e) {
241 fail("Should have been able to close the connection");
242 }
243
244 }
245
246 @Override
247 public void beforeCompletion() {
248 try {
249 conn = (ManagedConnection<?>) ds.getConnection();
250 assertNotNull(conn);
251 } catch (final SQLException e) {
252 fail("Could not get connection");
253 }
254 }
255 });
256 transactionManager.commit();
257 }
258
259 @Test
260 public void testGetConnectionInAfterCompletion() throws Exception {
261 try (DelegatingConnection<?> connection = (DelegatingConnection<?>) newConnection()) {
262
263 transactionManager.getTransaction().registerSynchronization(new SynchronizationAdapter() {
264 @Override
265 public void afterCompletion(final int i) {
266 try {
267 final Connection connection1 = ds.getConnection();
268 try {
269 connection1.getWarnings();
270 fail("Could operate on closed connection");
271 } catch (final SQLException e) {
272
273 }
274 } catch (final SQLException e) {
275 fail("Should have been able to get connection");
276 }
277 }
278 });
279 }
280 transactionManager.commit();
281 }
282
283 @Override
284 @Test
285 public void testHashCode() throws Exception {
286 try (Connection conn1 = newConnection()) {
287 assertNotNull(conn1);
288 try (Connection conn2 = newConnection()) {
289 assertNotNull(conn2);
290
291
292 Assertions.assertNotEquals(conn1.hashCode(), conn2.hashCode());
293 }
294 }
295 }
296
297
298
299
300 @Override
301 @Test
302 public void testManagedConnectionEqualsFail() throws Exception {
303
304
305
306 }
307
308 @Override
309 @Test
310 public void testMaxTotal() throws Exception {
311 final Transaction[] transactions = new Transaction[getMaxTotal()];
312 final Connection[] c = new Connection[getMaxTotal()];
313 for (int i = 0; i < c.length; i++) {
314
315 c[i] = newConnection();
316 assertNotNull(c[i]);
317
318
319 transactions[i] = transactionManager.suspend();
320 assertNotNull(transactions[i]);
321 transactionManager.begin();
322 }
323
324 try {
325 newConnection();
326 fail("Allowed to open more than DefaultMaxTotal connections.");
327 } catch (final java.sql.SQLException e) {
328
329
330 } finally {
331 transactionManager.commit();
332 for (int i = 0; i < c.length; i++) {
333 transactionManager.resume(transactions[i]);
334 c[i].close();
335 transactionManager.commit();
336 }
337 }
338 }
339
340 @Override
341 @Test
342 public void testNestedConnections() {
343
344 }
345
346 @Test
347 public void testReadOnly() throws Exception {
348 try (Connection connection = newConnection()) {
349
350
351
352
353 assertTrue(connection.isReadOnly(), "Connection be read-only");
354
355
356 try {
357 connection.setReadOnly(true);
358 fail("setReadOnly method should be disabled while enlisted in a transaction");
359 } catch (final SQLException e) {
360
361 }
362
363
364 assertTrue(connection.isReadOnly(), "Connection be read-only");
365
366
367 try {
368 connection.setReadOnly(false);
369 fail("setReadOnly method should be disabled while enlisted in a transaction");
370 } catch (final SQLException e) {
371
372 }
373
374
375 assertTrue(connection.isReadOnly(), "Connection be read-only");
376
377
378 }
379 }
380
381 @Override
382 @Test
383 public void testSharedConnection() throws Exception {
384 try (DelegatingConnection<?> connectionA = (DelegatingConnection<?>) newConnection();
385 DelegatingConnection<?> connectionB = (DelegatingConnection<?>) newConnection()) {
386 assertNotEquals(connectionA, connectionB);
387 assertNotEquals(connectionB, connectionA);
388 assertTrue(connectionA.innermostDelegateEquals(connectionB.getInnermostDelegate()));
389 assertTrue(connectionB.innermostDelegateEquals(connectionA.getInnermostDelegate()));
390 }
391 }
392
393 @Test
394 public void testSharedTransactionConversion() throws Exception {
395 try (DelegatingConnection<?> connectionA = (DelegatingConnection<?>) newConnection();
396 DelegatingConnection<?> connectionB = (DelegatingConnection<?>) newConnection()) {
397
398 assertNotEquals(connectionA, connectionB);
399 assertNotEquals(connectionB, connectionA);
400 assertTrue(connectionA.innermostDelegateEquals(connectionB.getInnermostDelegate()));
401 assertTrue(connectionB.innermostDelegateEquals(connectionA.getInnermostDelegate()));
402
403 transactionManager.commit();
404
405
406 connectionA.getAutoCommit();
407 connectionB.getAutoCommit();
408
409
410 assertNotEquals(connectionA, connectionB);
411 assertNotEquals(connectionB, connectionA);
412 assertFalse(connectionA.innermostDelegateEquals(connectionB.getInnermostDelegate()));
413 assertFalse(connectionB.innermostDelegateEquals(connectionA.getInnermostDelegate()));
414
415 transactionManager.begin();
416
417
418 connectionA.getAutoCommit();
419 connectionB.getAutoCommit();
420
421
422 assertNotEquals(connectionA, connectionB);
423 assertNotEquals(connectionB, connectionA);
424 assertTrue(connectionA.innermostDelegateEquals(connectionB.getInnermostDelegate()));
425 assertTrue(connectionB.innermostDelegateEquals(connectionA.getInnermostDelegate()));
426 }
427 }
428 }