Skip to content

Commit 8d954b5

Browse files
froqueeddumelendez
andauthored
Fix connection leak in JdbcDatabaseDelegate (#9662)
Co-authored-by: Eddú Meléndez Gonzales <[email protected]>
1 parent 705d59b commit 8d954b5

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

modules/jdbc/src/main/java/org/testcontainers/jdbc/JdbcDatabaseDelegate.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.testcontainers.exception.ConnectionCreationException;
77
import org.testcontainers.ext.ScriptUtils;
88

9+
import java.sql.Connection;
910
import java.sql.SQLException;
1011
import java.sql.Statement;
1112

@@ -17,6 +18,8 @@ public class JdbcDatabaseDelegate extends AbstractDatabaseDelegate<Statement> {
1718

1819
private JdbcDatabaseContainer container;
1920

21+
private Connection connection;
22+
2023
private String queryString;
2124

2225
public JdbcDatabaseDelegate(JdbcDatabaseContainer container, String queryString) {
@@ -27,7 +30,8 @@ public JdbcDatabaseDelegate(JdbcDatabaseContainer container, String queryString)
2730
@Override
2831
protected Statement createNewConnection() {
2932
try {
30-
return container.createConnection(queryString).createStatement();
33+
connection = container.createConnection(queryString);
34+
return connection.createStatement();
3135
} catch (SQLException e) {
3236
log.error("Could not obtain JDBC connection");
3337
throw new ConnectionCreationException("Could not obtain JDBC connection", e);
@@ -65,6 +69,7 @@ public void execute(
6569
protected void closeConnectionQuietly(Statement statement) {
6670
try {
6771
statement.close();
72+
connection.close();
6873
} catch (Exception e) {
6974
log.error("Could not close JDBC connection", e);
7075
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package org.testcontainers.jdbc;
2+
3+
import lombok.NonNull;
4+
import org.junit.Assert;
5+
import org.junit.Test;
6+
import org.mockito.Mockito;
7+
import org.slf4j.Logger;
8+
import org.testcontainers.containers.JdbcDatabaseContainer;
9+
import org.testcontainers.utility.DockerImageName;
10+
11+
import java.sql.Connection;
12+
import java.sql.SQLException;
13+
import java.sql.Statement;
14+
import java.util.ArrayList;
15+
import java.util.List;
16+
17+
import static org.mockito.Mockito.mock;
18+
import static org.mockito.Mockito.when;
19+
20+
public class JdbcDatabaseDelegateTest {
21+
22+
@Test
23+
public void testLeakedConnections() {
24+
final JdbcDatabaseContainerStub stub = new JdbcDatabaseContainerStub(DockerImageName.parse("something"));
25+
try (JdbcDatabaseDelegate delegate = new JdbcDatabaseDelegate(stub, "")) {
26+
delegate.execute("foo", null, 0, false, false);
27+
}
28+
Assert.assertEquals(0, stub.openConnectionsList.size());
29+
}
30+
31+
static class JdbcDatabaseContainerStub extends JdbcDatabaseContainer {
32+
33+
List<Connection> openConnectionsList = new ArrayList<>();
34+
35+
public JdbcDatabaseContainerStub(@NonNull DockerImageName dockerImageName) {
36+
super(dockerImageName);
37+
}
38+
39+
@Override
40+
public String getDriverClassName() {
41+
return null;
42+
}
43+
44+
@Override
45+
public String getJdbcUrl() {
46+
return null;
47+
}
48+
49+
@Override
50+
public String getUsername() {
51+
return null;
52+
}
53+
54+
@Override
55+
public String getPassword() {
56+
return null;
57+
}
58+
59+
@Override
60+
protected String getTestQueryString() {
61+
return null;
62+
}
63+
64+
@Override
65+
public boolean isRunning() {
66+
return true;
67+
}
68+
69+
@Override
70+
public Connection createConnection(String queryString) throws NoDriverFoundException, SQLException {
71+
final Connection connection = mock(Connection.class);
72+
openConnectionsList.add(connection);
73+
when(connection.createStatement()).thenReturn(mock(Statement.class));
74+
connection.close();
75+
Mockito.doAnswer(ignore -> openConnectionsList.remove(connection)).when(connection).close();
76+
return connection;
77+
}
78+
79+
@Override
80+
protected Logger logger() {
81+
return mock(Logger.class);
82+
}
83+
84+
@Override
85+
public void setDockerImageName(@NonNull String dockerImageName) {}
86+
}
87+
}

0 commit comments

Comments
 (0)