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