1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.jdbc;
17
18 import static org.junit.jupiter.api.Assertions.*;
19
20 import java.sql.Connection;
21 import java.sql.PreparedStatement;
22 import java.sql.ResultSet;
23 import java.sql.SQLException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Properties;
27 import java.util.concurrent.TimeUnit;
28
29 import org.apache.ibatis.BaseDataTest;
30 import org.apache.ibatis.datasource.pooled.PooledDataSource;
31 import org.hsqldb.jdbc.JDBCConnection;
32 import org.junit.jupiter.api.Disabled;
33 import org.junit.jupiter.api.Test;
34
35 class PooledDataSourceTest extends BaseDataTest {
36
37 @Test
38 void shouldProperlyMaintainPoolOf3ActiveAnd2IdleConnections() throws Exception {
39 PooledDataSource ds = createPooledDataSource(JPETSTORE_PROPERTIES);
40 try {
41 runScript(ds, JPETSTORE_DDL);
42 ds.setDefaultAutoCommit(false);
43 ds.setDriverProperties(new Properties() {
44 {
45 setProperty("username", "sa");
46 setProperty("password", "");
47 }
48 });
49 ds.setPoolMaximumActiveConnections(3);
50 ds.setPoolMaximumIdleConnections(2);
51 ds.setPoolMaximumCheckoutTime(10000);
52 ds.setPoolPingConnectionsNotUsedFor(1);
53 ds.setPoolPingEnabled(true);
54 ds.setPoolPingQuery("SELECT * FROM PRODUCT");
55 ds.setPoolTimeToWait(10000);
56 ds.setLogWriter(null);
57 List<Connection> connections = new ArrayList<>();
58 for (int i = 0; i < 3; i++) {
59 connections.add(ds.getConnection());
60 }
61 assertEquals(3, ds.getPoolState().getActiveConnectionCount());
62 for (Connection c : connections) {
63 c.close();
64 }
65 assertEquals(2, ds.getPoolState().getIdleConnectionCount());
66 assertEquals(4, ds.getPoolState().getRequestCount());
67 assertEquals(0, ds.getPoolState().getBadConnectionCount());
68 assertEquals(0, ds.getPoolState().getHadToWaitCount());
69 assertEquals(0, ds.getPoolState().getAverageOverdueCheckoutTime());
70 assertEquals(0, ds.getPoolState().getClaimedOverdueConnectionCount());
71 assertEquals(0, ds.getPoolState().getAverageWaitTime());
72 assertNotNull(ds.getPoolState().toString());
73 } finally {
74 ds.forceCloseAll();
75 }
76 }
77
78 @Test
79 void shouldNotFailCallingToStringOverAnInvalidConnection() throws Exception {
80 PooledDataSource ds = createPooledDataSource(JPETSTORE_PROPERTIES);
81 Connection c = ds.getConnection();
82 c.close();
83 c.toString();
84 }
85
86 @Test
87 void ShouldReturnRealConnection() throws Exception {
88 PooledDataSource ds = createPooledDataSource(JPETSTORE_PROPERTIES);
89 Connection c = ds.getConnection();
90 JDBCConnection realConnection = (JDBCConnection) PooledDataSource.unwrapConnection(c);
91 c.close();
92 }
93
94 @Disabled("See the comments")
95 @Test
96 void shouldReconnectWhenServerKilledLeakedConnection() throws Exception {
97
98
99
100
101
102
103
104 final String URL = "jdbc:mysql://localhost:3306/test";
105 final String USERNAME = "admin";
106 final String PASSWORD = "";
107
108 PooledDataSource ds = new PooledDataSource();
109 ds.setDriver("com.mysql.jdbc.Driver");
110 ds.setUrl(URL);
111 ds.setUsername(USERNAME);
112 ds.setPassword(PASSWORD);
113 ds.setPoolMaximumActiveConnections(1);
114 ds.setPoolMaximumIdleConnections(1);
115 ds.setPoolTimeToWait(1000);
116 ds.setPoolMaximumCheckoutTime(2000);
117 ds.setPoolPingEnabled(true);
118 ds.setPoolPingQuery("select 1");
119 ds.setDefaultAutoCommit(true);
120
121 ds.setPoolPingConnectionsNotUsedFor(1000);
122
123 Connection con = ds.getConnection();
124 exexuteQuery(con);
125
126
127
128
129 Thread.sleep(TimeUnit.SECONDS.toMillis(3));
130
131 con.close();
132
133
134 con = ds.getConnection();
135 exexuteQuery(con);
136 con.close();
137 }
138
139 private void exexuteQuery(Connection con) throws SQLException {
140 try (PreparedStatement st = con.prepareStatement("select 1");
141 ResultSet rs = st.executeQuery()) {
142 while (rs.next()) {
143 assertEquals(1, rs.getInt(1));
144 }
145 }
146 }
147 }