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