Skip to content

Commit 3858aff

Browse files
vcvitalybsideup
andauthored
Improve log messages when database container test query fails (#3015)
Co-authored-by: Sergei Egorov <[email protected]>
1 parent 137b00d commit 3858aff

File tree

3 files changed

+88
-16
lines changed

3 files changed

+88
-16
lines changed

modules/jdbc/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ dependencies {
1111
testCompile 'com.zaxxer:HikariCP-java6:2.3.13'
1212
testCompile 'com.googlecode.junit-toolbox:junit-toolbox:2.4'
1313
testCompile 'org.rnorth.visible-assertions:visible-assertions:2.1.2'
14+
testCompile 'org.assertj:assertj-core:3.16.1'
1415
}

modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.testcontainers.containers;
22

33
import com.github.dockerjava.api.command.InspectContainerResponse;
4+
import java.sql.Statement;
45
import lombok.NonNull;
6+
import lombok.SneakyThrows;
57
import org.apache.commons.lang.StringUtils;
68
import org.jetbrains.annotations.NotNull;
79
import org.testcontainers.containers.traits.LinkableContainer;
@@ -130,25 +132,23 @@ public SELF withInitScript(String initScriptPath) {
130132
return self();
131133
}
132134

135+
@SneakyThrows(InterruptedException.class)
133136
@Override
134137
protected void waitUntilContainerStarted() {
135138
logger().info("Waiting for database connection to become available at {} using query '{}'", getJdbcUrl(), getTestQueryString());
136139

137140
// Repeatedly try and open a connection to the DB and execute a test query
138141
long start = System.currentTimeMillis();
139-
try {
140-
while (System.currentTimeMillis() < start + (1000 * startupTimeoutSeconds)) {
141-
try {
142-
if (!isRunning()) {
143-
Thread.sleep(100L);
144-
continue; // Don't attempt to connect yet
145-
}
146142

147-
try (Connection connection = createConnection("")) {
148-
boolean testQuerySucceeded = connection.createStatement().execute(this.getTestQueryString());
149-
if (testQuerySucceeded) {
150-
break;
151-
}
143+
while (System.currentTimeMillis() < start + (1000 * startupTimeoutSeconds)) {
144+
if (!isRunning()) {
145+
Thread.sleep(100L);
146+
} else {
147+
try (Statement statement = createConnection("").createStatement()) {
148+
boolean testQuerySucceeded = statement.execute(this.getTestQueryString());
149+
if (testQuerySucceeded) {
150+
logger().info("Container is started (JDBC URL: {})", this.getJdbcUrl());
151+
return;
152152
}
153153
} catch (NoDriverFoundException e) {
154154
// we explicitly want this exception to fail fast without retries
@@ -159,12 +159,12 @@ protected void waitUntilContainerStarted() {
159159
Thread.sleep(100L);
160160
}
161161
}
162-
} catch (InterruptedException e) {
163-
Thread.currentThread().interrupt();
164-
throw new ContainerLaunchException("Container startup wait was interrupted", e);
165162
}
166163

167-
logger().info("Container is started (JDBC URL: {})", JdbcDatabaseContainer.this.getJdbcUrl());
164+
throw new IllegalStateException(
165+
String.format("Container is started, but cannot be accessed by (JDBC URL: %s), please check container logs",
166+
this.getJdbcUrl())
167+
);
168168
}
169169

170170
@Override
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package org.testcontainers.containers;
2+
3+
import java.sql.Connection;
4+
import java.sql.SQLException;
5+
import lombok.NonNull;
6+
import org.junit.Test;
7+
import org.slf4j.Logger;
8+
9+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
10+
import static org.mockito.Mockito.mock;
11+
12+
public class JdbcDatabaseContainerTest {
13+
14+
@Test
15+
public void anExceptionIsThrownIfJdbcIsNotAvailable() {
16+
JdbcDatabaseContainer<?> jdbcContainer = new JdbcDatabaseContainerStub("mysql:latest")
17+
.withStartupTimeoutSeconds(1);
18+
19+
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(jdbcContainer::waitUntilContainerStarted);
20+
}
21+
22+
static class JdbcDatabaseContainerStub extends JdbcDatabaseContainer {
23+
24+
public JdbcDatabaseContainerStub(@NonNull String dockerImageName) {
25+
super(dockerImageName);
26+
}
27+
28+
@Override
29+
public String getDriverClassName() {
30+
return null;
31+
}
32+
33+
@Override
34+
public String getJdbcUrl() {
35+
return null;
36+
}
37+
38+
@Override
39+
public String getUsername() {
40+
return null;
41+
}
42+
43+
@Override
44+
public String getPassword() {
45+
return null;
46+
}
47+
48+
@Override
49+
protected String getTestQueryString() {
50+
return null;
51+
}
52+
53+
@Override
54+
public boolean isRunning() {
55+
return true;
56+
}
57+
58+
@Override
59+
public Connection createConnection(String queryString) throws SQLException, NoDriverFoundException {
60+
throw new SQLException("Could not create new connection");
61+
}
62+
63+
@Override
64+
protected Logger logger() {
65+
return mock(Logger.class);
66+
}
67+
68+
@Override
69+
public void setDockerImageName(@NonNull String dockerImageName) {}
70+
}
71+
}

0 commit comments

Comments
 (0)