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.assertNull;
26 import static org.junit.jupiter.api.Assertions.assertSame;
27 import static org.junit.jupiter.api.Assertions.assertThrows;
28 import static org.junit.jupiter.api.Assertions.assertTrue;
29 import static org.junit.jupiter.api.Assertions.fail;
30
31 import java.sql.CallableStatement;
32 import java.sql.Connection;
33 import java.sql.PreparedStatement;
34 import java.sql.ResultSet;
35 import java.sql.SQLException;
36 import java.sql.Statement;
37 import java.time.Duration;
38 import java.util.Hashtable;
39 import java.util.Random;
40 import java.util.Stack;
41
42 import org.junit.jupiter.api.AfterEach;
43 import org.junit.jupiter.api.Test;
44
45
46
47
48
49
50
51
52
53
54 public abstract class TestConnectionPool {
55
56 protected class PoolTest implements Runnable {
57
58
59
60 private final Duration connHoldDuration;
61
62 private final int numStatements;
63
64 private volatile boolean isRun;
65
66 private String state;
67
68 private final Thread thread;
69
70 private Throwable thrown;
71
72 private final Random random = new Random();
73
74
75 private final long createdMillis;
76 private long started;
77 private long ended;
78 private long preconnected;
79 private long connected;
80 private long postconnected;
81 private int loops;
82 private int connHash;
83
84 private final boolean stopOnException;
85
86 private final boolean loopOnce;
87
88 public PoolTest(final ThreadGroup threadGroup, final Duration connHoldDuration, final boolean isStopOnException) {
89 this(threadGroup, connHoldDuration, isStopOnException, false, 1);
90 }
91
92 private PoolTest(final ThreadGroup threadGroup, final Duration connHoldDuration, final boolean isStopOnException, final boolean once, final int numStatements) {
93 this.loopOnce = once;
94 this.connHoldDuration = connHoldDuration;
95 stopOnException = isStopOnException;
96 isRun = true;
97 thrown = null;
98 thread =
99 new Thread(threadGroup, this, "Thread+" + currentThreadCount++);
100 thread.setDaemon(false);
101 createdMillis = timeStampMillis();
102 this.numStatements = numStatements;
103 }
104
105 public PoolTest(final ThreadGroup threadGroup, final Duration connHoldDuration, final boolean isStopOnException, final int numStatements) {
106 this(threadGroup, connHoldDuration, isStopOnException, false, numStatements);
107 }
108
109 public Thread getThread() {
110 return thread;
111 }
112
113 @Override
114 public void run() {
115 started = timeStampMillis();
116 try {
117 while (isRun) {
118 loops++;
119 state = "Getting Connection";
120 preconnected = timeStampMillis();
121 try (Connection conn = getConnection()) {
122 connHash = System.identityHashCode(((DelegatingConnection<?>) conn).getInnermostDelegate());
123 connected = timeStampMillis();
124 state = "Using Connection";
125 assertNotNull(conn);
126 final String sql = numStatements == 1 ? "select * from dual" : "select count " + random.nextInt(numStatements - 1);
127 try (PreparedStatement stmt = conn.prepareStatement(sql)) {
128 assertNotNull(stmt);
129 try (ResultSet rset = stmt.executeQuery()) {
130 assertNotNull(rset);
131 assertTrue(rset.next());
132 state = "Holding Connection";
133 Thread.sleep(connHoldDuration.toMillis());
134 state = "Closing ResultSet";
135 }
136 state = "Closing Statement";
137 }
138 state = "Closing Connection";
139 }
140 postconnected = timeStampMillis();
141 state = "Closed";
142 if (loopOnce) {
143 break;
144 }
145 }
146 state = DONE;
147 } catch (final Throwable t) {
148 thrown = t;
149 if (!stopOnException) {
150 throw new RuntimeException();
151 }
152 } finally {
153 ended = timeStampMillis();
154 }
155 }
156
157 public void start(){
158 thread.start();
159 }
160
161 public void stop() {
162 isRun = false;
163 }
164 }
165
166 final class TestThread implements Runnable {
167 final Random random = new Random();
168 boolean complete;
169 boolean failed;
170 int iter = 100;
171 int delay = 50;
172
173 public TestThread() {
174 }
175
176 public TestThread(final int iter) {
177 this.iter = iter;
178 }
179
180 public TestThread(final int iter, final int delay) {
181 this.iter = iter;
182 this.delay = delay;
183 }
184
185 public boolean complete() {
186 return complete;
187 }
188
189 public boolean failed() {
190 return failed;
191 }
192
193 @Override
194 public void run() {
195 for (int i = 0; i < iter; i++) {
196 try {
197 Thread.sleep(random.nextInt(delay));
198 } catch (final Exception e) {
199
200 }
201 try (Connection conn = newConnection();
202 PreparedStatement stmt = conn.prepareStatement("select 'literal', SYSDATE from dual");
203 ResultSet rset = stmt.executeQuery()) {
204 try {
205 Thread.sleep(random.nextInt(delay));
206 } catch (final Exception ignore) {
207
208 }
209 } catch (final Exception e) {
210 e.printStackTrace();
211 failed = true;
212 complete = true;
213 break;
214 }
215 }
216 complete = true;
217 }
218 }
219
220 private static final Duration MAX_WAIT_DURATION = Duration.ofMillis(100);
221
222 private static final boolean DISPLAY_THREAD_DETAILS=
223 Boolean.getBoolean("TestConnectionPool.display.thread.details");
224
225
226
227
228 private static int currentThreadCount;
229
230 private static final String DONE = "Done";
231
232
233 protected final Stack<Connection> connectionStack = new Stack<>();
234
235
236 protected void assertBackPointers(final Connection conn, final Statement statement) throws SQLException {
237 assertFalse(conn.isClosed());
238 assertFalse(isClosed(statement));
239
240 assertSame(conn, statement.getConnection(),
241 "statement.getConnection() should return the exact same connection instance that was used to create the statement");
242
243 final ResultSet resultSet = statement.getResultSet();
244 assertFalse(isClosed(resultSet));
245 assertSame(statement, resultSet.getStatement(),
246 "resultSet.getStatement() should return the exact same statement instance that was used to create the result set");
247
248 final ResultSet executeResultSet = statement.executeQuery("select * from dual");
249 assertFalse(isClosed(executeResultSet));
250 assertSame(statement, executeResultSet.getStatement(),
251 "resultSet.getStatement() should return the exact same statement instance that was used to create the result set");
252
253 final ResultSet keysResultSet = statement.getGeneratedKeys();
254 assertFalse(isClosed(keysResultSet));
255 assertSame(statement, keysResultSet.getStatement(),
256 "resultSet.getStatement() should return the exact same statement instance that was used to create the result set");
257
258 ResultSet preparedResultSet = null;
259 if (statement instanceof PreparedStatement) {
260 final PreparedStatement preparedStatement = (PreparedStatement) statement;
261 preparedResultSet = preparedStatement.executeQuery();
262 assertFalse(isClosed(preparedResultSet));
263 assertSame(statement, preparedResultSet.getStatement(),
264 "resultSet.getStatement() should return the exact same statement instance that was used to create the result set");
265 }
266
267 resultSet.getStatement().getConnection().close();
268 assertTrue(conn.isClosed());
269 assertTrue(isClosed(statement));
270 assertTrue(isClosed(resultSet));
271 assertTrue(isClosed(executeResultSet));
272 assertTrue(isClosed(keysResultSet));
273 if (preparedResultSet != null) {
274 assertTrue(isClosed(preparedResultSet));
275 }
276 }
277
278 protected abstract Connection getConnection() throws Exception;
279
280 protected int getMaxTotal() {
281 return 10;
282 }
283
284 protected Duration getMaxWaitDuration() {
285 return MAX_WAIT_DURATION;
286 }
287
288 protected String getUsername(final Connection conn) throws SQLException {
289 try (final Statement stmt = conn.createStatement(); final ResultSet rs = stmt.executeQuery("select username")) {
290 if (rs.next()) {
291 return rs.getString(1);
292 }
293 }
294 return null;
295 }
296
297 protected boolean isClosed(final ResultSet resultSet) {
298 try {
299 resultSet.getWarnings();
300 return false;
301 } catch (final SQLException e) {
302
303
304
305
306 return true;
307 }
308 }
309
310 protected boolean isClosed(final Statement statement) {
311 try {
312 statement.getWarnings();
313 return false;
314 } catch (final SQLException e) {
315
316
317
318
319 return true;
320 }
321 }
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337 protected void multipleThreads(final Duration holdDuration,
338 final boolean expectError, final boolean loopOnce,
339 final Duration maxWaitDuration) throws Exception {
340 multipleThreads(holdDuration, expectError, loopOnce, maxWaitDuration, 1, 2 * getMaxTotal(), 300);
341 }
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359 protected void multipleThreads(final Duration holdDuration,
360 final boolean expectError, final boolean loopOnce,
361 final Duration maxWaitDuration, final int numStatements, final int numThreads, final long duration) throws Exception {
362 final long startTimeMillis = timeStampMillis();
363 final PoolTest[] pts = new PoolTest[numThreads];
364
365 final ThreadGroup threadGroup = new ThreadGroup("foo") {
366 @Override
367 public void uncaughtException(final Thread t, final Throwable e) {
368 for (final PoolTest pt : pts) {
369 pt.stop();
370 }
371 }
372 };
373
374 for (int i = 0; i < pts.length; i++) {
375 pts[i] = new PoolTest(threadGroup, holdDuration, expectError, loopOnce, numStatements);
376 }
377
378 for (final PoolTest pt : pts) {
379 pt.start();
380 }
381
382
383 Thread.sleep(duration);
384
385
386 for (final PoolTest pt : pts) {
387 pt.stop();
388 }
389
390
391
392
393
394 int done = 0;
395 int failed = 0;
396 int didNotRun = 0;
397 int loops = 0;
398 for (final PoolTest poolTest : pts) {
399 poolTest.thread.join();
400 loops += poolTest.loops;
401 final String state = poolTest.state;
402 if (DONE.equals(state)) {
403 done++;
404 }
405 if (poolTest.loops == 0) {
406 didNotRun++;
407 }
408 final Throwable thrown = poolTest.thrown;
409 if (thrown != null) {
410 failed++;
411 if (!expectError || !(thrown instanceof SQLException)) {
412 System.err.println("Unexpected error: " + thrown.getMessage());
413 }
414 }
415 }
416
417 final long timeMillis = timeStampMillis() - startTimeMillis;
418
419 println("Multithread test time = " + timeMillis
420 + " ms. Threads: " + pts.length
421 + ". Loops: " + loops
422 + ". Hold time: " + holdDuration
423 + ". maxWaitMillis: " + maxWaitDuration
424 + ". Done: " + done
425 + ". Did not run: " + didNotRun
426 + ". Failed: " + failed
427 + ". expectError: " + expectError);
428
429 if (expectError) {
430 if (DISPLAY_THREAD_DETAILS || pts.length / 2 != failed) {
431 final long offset = pts[0].createdMillis - 1000;
432 println("Offset: " + offset);
433 for (int i = 0; i < pts.length; i++) {
434 final PoolTest pt = pts[i];
435
436 println("Pre: " + (pt.preconnected-offset)
437 + ". Post: " + (pt.postconnected != 0 ? Long.toString(pt.postconnected-offset): "-")
438 + ". Hash: " + pt.connHash
439 + ". Startup: " + (pt.started-pt.createdMillis)
440 + ". getConn(): " + (pt.connected != 0 ? Long.toString(pt.connected-pt.preconnected) : "-")
441 + ". Runtime: " + (pt.ended-pt.started)
442 + ". IDX: " + i
443 + ". Loops: " + pt.loops
444 + ". State: " + pt.state
445 + ". thrown: "+ pt.thrown
446 + ".");
447
448 }
449 }
450 if (didNotRun > 0) {
451 println("NOTE: some threads did not run the code: " + didNotRun);
452 }
453
454 assertTrue(failed > 0, "Expected some of the threads to fail");
455
456 assertEquals(pts.length / 2, failed + didNotRun, "WARNING: Expected half the threads to fail");
457 } else {
458 assertEquals(0, failed, "Did not expect any threads to fail");
459 }
460 }
461
462
463
464
465
466
467
468 @SuppressWarnings("resource")
469 protected Connection newConnection() throws Exception {
470 return connectionStack.push(getConnection());
471 }
472
473 void println(final String string) {
474 if (Boolean.getBoolean(getClass().getSimpleName() + ".debug")) {
475 System.out.println(string);
476 }
477 }
478
479 @AfterEach
480 public void tearDown() throws Exception {
481
482 while (!connectionStack.isEmpty()) {
483 Utils.closeQuietly((AutoCloseable) connectionStack.pop());
484 }
485 }
486
487 @Test
488 public void testAutoCommitBehavior() throws Exception {
489 final Connection conn0 = newConnection();
490 assertNotNull(conn0, "connection should not be null");
491 assertTrue(conn0.getAutoCommit(), "autocommit should be true for conn0");
492
493 final Connection conn1 = newConnection();
494 assertTrue(conn1.getAutoCommit(), "autocommit should be true for conn1");
495 conn1.close();
496
497 assertTrue(conn0.getAutoCommit(), "autocommit should be true for conn0");
498 conn0.setAutoCommit(false);
499 assertFalse(conn0.getAutoCommit(), "autocommit should be false for conn0");
500 conn0.close();
501
502 final Connection conn2 = newConnection();
503 assertTrue(conn2.getAutoCommit(), "autocommit should be true for conn2");
504
505 final Connection conn3 = newConnection();
506 assertTrue(conn3.getAutoCommit(), "autocommit should be true for conn3");
507
508 conn2.close();
509
510 conn3.close();
511 }
512
513 @Test
514 public void testBackPointers() throws Exception {
515
516 Connection conn = newConnection();
517 assertBackPointers(conn, conn.createStatement());
518 conn = newConnection();
519 assertBackPointers(conn, conn.createStatement(0, 0));
520 conn = newConnection();
521 assertBackPointers(conn, conn.createStatement(0, 0, 0));
522
523
524 conn = newConnection();
525 assertBackPointers(conn, conn.prepareStatement("select * from dual"));
526 conn = newConnection();
527 assertBackPointers(conn, conn.prepareStatement("select * from dual", 0));
528 conn = newConnection();
529 assertBackPointers(conn, conn.prepareStatement("select * from dual", 0, 0));
530 conn = newConnection();
531 assertBackPointers(conn, conn.prepareStatement("select * from dual", 0, 0, 0));
532 conn = newConnection();
533 assertBackPointers(conn, conn.prepareStatement("select * from dual", new int[0]));
534 conn = newConnection();
535 assertBackPointers(conn, conn.prepareStatement("select * from dual", new String[0]));
536
537
538 conn = newConnection();
539 assertBackPointers(conn, conn.prepareCall("select * from dual"));
540 conn = newConnection();
541 assertBackPointers(conn, conn.prepareCall("select * from dual", 0, 0));
542 conn = newConnection();
543 assertBackPointers(conn, conn.prepareCall("select * from dual", 0, 0, 0));
544 }
545
546 @Test
547 public void testCanCloseCallableStatementTwice() throws Exception {
548 try (Connection conn = newConnection()) {
549 assertNotNull(conn);
550 assertFalse(conn.isClosed());
551 for (int i = 0; i < 2; i++) {
552 final PreparedStatement stmt = conn.prepareCall("select * from dual");
553 assertNotNull(stmt);
554 assertFalse(isClosed(stmt));
555 stmt.close();
556 assertTrue(isClosed(stmt));
557 stmt.close();
558 assertTrue(isClosed(stmt));
559 stmt.close();
560 assertTrue(isClosed(stmt));
561 }
562 }
563 }
564
565
566
567
568
569 @Test
570 public void testCanCloseConnectionTwice() throws Exception {
571 for (int i = 0; i < getMaxTotal(); i++) {
572 final Connection conn = newConnection();
573 assertNotNull(conn);
574 assertFalse(conn.isClosed());
575 conn.close();
576 assertTrue(conn.isClosed());
577 conn.close();
578 assertTrue(conn.isClosed());
579 }
580 }
581
582 @Test
583 public void testCanClosePreparedStatementTwice() throws Exception {
584 try (Connection conn = newConnection()) {
585 assertNotNull(conn);
586 assertFalse(conn.isClosed());
587 for (int i = 0; i < 2; i++) {
588 final PreparedStatement stmt = conn.prepareStatement("select * from dual");
589 assertNotNull(stmt);
590 assertFalse(isClosed(stmt));
591 stmt.close();
592 assertTrue(isClosed(stmt));
593 stmt.close();
594 assertTrue(isClosed(stmt));
595 stmt.close();
596 assertTrue(isClosed(stmt));
597 }
598 }
599 }
600
601 @Test
602 public void testCanCloseResultSetTwice() throws Exception {
603 try (Connection conn = newConnection()) {
604 assertNotNull(conn);
605 assertFalse(conn.isClosed());
606 for (int i = 0; i < 2; i++) {
607 final PreparedStatement stmt = conn.prepareStatement("select * from dual");
608 assertNotNull(stmt);
609 final ResultSet rset = stmt.executeQuery();
610 assertNotNull(rset);
611 assertFalse(isClosed(rset));
612 rset.close();
613 assertTrue(isClosed(rset));
614 rset.close();
615 assertTrue(isClosed(rset));
616 rset.close();
617 assertTrue(isClosed(rset));
618 }
619 }
620 }
621
622 @Test
623 public void testCanCloseStatementTwice() throws Exception {
624 final Connection conn = newConnection();
625 assertNotNull(conn);
626 assertFalse(conn.isClosed());
627 for (int i = 0; i < 2; i++) {
628 final Statement stmt = conn.createStatement();
629 assertNotNull(stmt);
630 assertFalse(isClosed(stmt));
631 stmt.close();
632 assertTrue(isClosed(stmt));
633 stmt.close();
634 assertTrue(isClosed(stmt));
635 stmt.close();
636 assertTrue(isClosed(stmt));
637 }
638 conn.close();
639 }
640
641 @Test
642 public void testClearWarnings() throws Exception {
643 final Connection[] c = new Connection[getMaxTotal()];
644 for (int i = 0; i < c.length; i++) {
645 c[i] = newConnection();
646 assertNotNull(c[i]);
647
648
649 try (CallableStatement cs = c[i].prepareCall("warning")) {
650
651 }
652 }
653
654 for (final Connection element : c) {
655 assertNotNull(element.getWarnings());
656 }
657
658 for (final Connection element : c) {
659 element.close();
660 }
661
662 for (int i = 0; i < c.length; i++) {
663 c[i] = newConnection();
664 }
665
666 for (final Connection element : c) {
667
668 assertNull(element.getWarnings());
669 }
670
671 for (final Connection element : c) {
672 element.close();
673 }
674 }
675
676 @Test
677 public void testClosing() throws Exception {
678 final Connection[] c = new Connection[getMaxTotal()];
679
680 for (int i = 0; i < c.length; i++) {
681 c[i] = newConnection();
682 }
683
684
685 c[0].close();
686 assertTrue(c[0].isClosed());
687
688
689 c[0] = newConnection();
690
691 for (final Connection element : c) {
692 element.close();
693 }
694 }
695
696
697 @Test
698 public void testConnectionsAreDistinct() throws Exception {
699 final Connection[] conn = new Connection[getMaxTotal()];
700 for(int i=0;i<conn.length;i++) {
701 conn[i] = newConnection();
702 for(int j=0;j<i;j++) {
703 assertNotSame(conn[j], conn[i]);
704 assertNotEquals(conn[j], conn[i]);
705 }
706 }
707 for (final Connection element : conn) {
708 element.close();
709 }
710 }
711
712
713 @Test
714 public void testHashCode() throws Exception {
715 final Connection conn1 = newConnection();
716 assertNotNull(conn1);
717 final Connection conn2 = newConnection();
718 assertNotNull(conn2);
719
720 assertTrue(conn1.hashCode() != conn2.hashCode());
721 }
722
723
724
725
726
727 @Test
728 public void testHashing() throws Exception {
729 final Connection con = getConnection();
730 final Hashtable<Connection, String> hash = new Hashtable<>();
731 hash.put(con, "test");
732 assertEquals("test", hash.get(con));
733 assertTrue(hash.containsKey(con));
734 assertTrue(hash.contains("test"));
735 hash.clear();
736 con.close();
737 }
738
739 @Test
740 public void testIsClosed() throws Exception {
741 for (int i = 0; i < getMaxTotal(); i++) {
742 @SuppressWarnings("resource")
743 final Connection conn = newConnection();
744 try {
745 assertNotNull(conn);
746 assertFalse(conn.isClosed());
747 try (PreparedStatement stmt = conn.prepareStatement("select * from dual")) {
748 assertNotNull(stmt);
749 try (ResultSet rset = stmt.executeQuery()) {
750 assertNotNull(rset);
751 assertTrue(rset.next());
752 }
753 }
754 } finally {
755 conn.close();
756 }
757 assertTrue(conn.isClosed());
758 }
759 }
760
761 @Test
762 public void testMaxTotal() throws Exception {
763 final Connection[] c = new Connection[getMaxTotal()];
764 for (int i = 0; i < c.length; i++) {
765 c[i] = newConnection();
766 assertNotNull(c[i]);
767 }
768
769
770
771 assertThrows(SQLException.class, this::newConnection);
772
773 for (final Connection element : c) {
774 element.close();
775 }
776 }
777
778
779
780 @Test
781 public void testNoRsetClose() throws Exception {
782 try (Connection conn = newConnection()) {
783 assertNotNull(conn);
784 try (PreparedStatement stmt = conn.prepareStatement("test")) {
785 assertNotNull(stmt);
786 final ResultSet rset = stmt.getResultSet();
787 assertNotNull(rset);
788
789 }
790 }
791 }
792
793 @Test
794 public void testOpening() throws Exception {
795 final Connection[] c = new Connection[getMaxTotal()];
796
797 for (int i = 0; i < c.length; i++) {
798 c[i] = newConnection();
799 assertNotNull(c[i]);
800 for (int j = 0; j <= i; j++) {
801 assertFalse(c[j].isClosed());
802 }
803 }
804
805 for (final Connection element : c) {
806 element.close();
807 }
808 }
809
810 @Test
811 public void testPooling() throws Exception {
812
813 final Connection[] c = new Connection[getMaxTotal()];
814 final Connection[] u = new Connection[getMaxTotal()];
815 for (int i = 0; i < c.length; i++) {
816 c[i] = newConnection();
817 if (!(c[i] instanceof DelegatingConnection)) {
818 for (int j = 0; j <= i; j++) {
819 c[j].close();
820 }
821 return;
822 }
823 u[i] = ((DelegatingConnection<?>) c[i]).getInnermostDelegate();
824 }
825
826
827 for (final Connection element : c) {
828 element.close();
829 try (Connection con = newConnection()) {
830 final Connection underCon = ((DelegatingConnection<?>) con).getInnermostDelegate();
831 assertNotNull(underCon, "Failed to get connection");
832 boolean found = false;
833 for (int j = 0; j < c.length; j++) {
834 if (underCon == u[j]) {
835 found = true;
836 break;
837 }
838 }
839 assertTrue(found, "New connection not from pool");
840 }
841 }
842 }
843
844
845
846
847 @Test
848 public void testPrepareStatementOptions() throws Exception {
849 try (Connection conn = newConnection()) {
850 assertNotNull(conn);
851 try (PreparedStatement stmt = conn.prepareStatement("select * from dual", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
852 assertNotNull(stmt);
853 try (ResultSet rset = stmt.executeQuery()) {
854 assertNotNull(rset);
855 assertTrue(rset.next());
856
857 assertEquals(ResultSet.TYPE_SCROLL_SENSITIVE, rset.getType());
858 assertEquals(ResultSet.CONCUR_UPDATABLE, rset.getConcurrency());
859
860 }
861 }
862 }
863 }
864
865 @Test
866 public void testRepeatedBorrowAndReturn() throws Exception {
867 for (int i = 0; i < 100; i++) {
868 try (Connection conn = newConnection()) {
869 assertNotNull(conn);
870 try (PreparedStatement stmt = conn.prepareStatement("select * from dual")) {
871 assertNotNull(stmt);
872 try (ResultSet rset = stmt.executeQuery()) {
873 assertNotNull(rset);
874 assertTrue(rset.next());
875 }
876 }
877 }
878 }
879 }
880
881 @Test
882 public void testSimple() throws Exception {
883 try (Connection conn = newConnection()) {
884 assertNotNull(conn);
885 try (PreparedStatement stmt = conn.prepareStatement("select * from dual")) {
886 assertNotNull(stmt);
887 try (ResultSet rset = stmt.executeQuery()) {
888 assertNotNull(rset);
889 assertTrue(rset.next());
890 }
891 }
892 }
893 }
894
895 @Test
896 public void testSimple2() throws Exception {
897 @SuppressWarnings("resource")
898 final Connection conn = newConnection();
899 assertNotNull(conn);
900 try {
901 try (PreparedStatement stmt = conn.prepareStatement("select * from dual")) {
902 assertNotNull(stmt);
903 try (ResultSet rset = stmt.executeQuery()) {
904 assertNotNull(rset);
905 assertTrue(rset.next());
906 }
907 }
908 try (PreparedStatement stmt = conn.prepareStatement("select * from dual")) {
909 assertNotNull(stmt);
910 try (ResultSet rset = stmt.executeQuery()) {
911 assertNotNull(rset);
912 assertTrue(rset.next());
913 }
914 }
915 } finally {
916 conn.close();
917 }
918 assertThrows(SQLException.class, conn::createStatement, "Can't use closed connections");
919
920 try (Connection conn2 = newConnection()) {
921 assertNotNull(conn2);
922 {
923 try (PreparedStatement stmt = conn2.prepareStatement("select * from dual")) {
924 assertNotNull(stmt);
925 try (ResultSet rset = stmt.executeQuery()) {
926 assertNotNull(rset);
927 assertTrue(rset.next());
928 }
929 }
930 }
931 {
932 try (PreparedStatement stmt = conn2.prepareStatement("select * from dual")) {
933 assertNotNull(stmt);
934 try (ResultSet rset = stmt.executeQuery()) {
935 assertNotNull(rset);
936 assertTrue(rset.next());
937 }
938 }
939 }
940 }
941 }
942
943 @Test
944 public void testThreaded() {
945 final TestThread[] threads = new TestThread[getMaxTotal()];
946 for (int i = 0; i < threads.length; i++) {
947 threads[i] = new TestThread(50, 50);
948 final Thread t = new Thread(threads[i]);
949 t.start();
950 }
951 for (int i = 0; i < threads.length; i++) {
952 while (!threads[i].complete()) {
953 try {
954 Thread.sleep(100L);
955 } catch (final Exception e) {
956
957 }
958 }
959 if (threads[i] != null && threads[i].failed()) {
960 fail("Thread failed: " + i);
961 }
962 }
963 }
964
965 long timeStampMillis() {
966 return System.currentTimeMillis();
967 }
968 }