Skip to content

Commit 58ae898

Browse files
committed
Create a Complex Wait Strategy and include it in the PostgreSQLContainer
1 parent bdd1aed commit 58ae898

File tree

4 files changed

+72
-6
lines changed

4 files changed

+72
-6
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.testcontainers.containers.wait.experimental;
2+
3+
import org.rnorth.ducttape.unreliables.Unreliables;
4+
import org.testcontainers.containers.output.WaitingConsumer;
5+
import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy;
6+
import org.testcontainers.containers.wait.strategy.WaitStrategy;
7+
8+
import java.util.ArrayList;
9+
import java.util.Arrays;
10+
import java.util.List;
11+
import java.util.concurrent.ExecutionException;
12+
import java.util.concurrent.ExecutorService;
13+
import java.util.concurrent.Executors;
14+
import java.util.concurrent.Future;
15+
import java.util.concurrent.TimeUnit;
16+
import java.util.stream.Collectors;
17+
18+
19+
public class ComplexWaitStrategy extends AbstractWaitStrategy {
20+
21+
private final List<WaitStrategy> waitStrategyList = new ArrayList<>();
22+
23+
@Override
24+
protected void waitUntilReady() {
25+
ExecutorService service = Executors.newFixedThreadPool(waitStrategyList.size());
26+
List<? extends Future<?>> futures = waitStrategyList.stream()
27+
.map(waitStrategy -> service.submit(() -> waitStrategy.waitUntilReady(waitStrategyTarget)))
28+
.collect(Collectors.toList());
29+
30+
Unreliables.retryUntilTrue(
31+
(int) startupTimeout.getSeconds(),
32+
TimeUnit.SECONDS,
33+
() -> futures.stream().anyMatch(Future::isDone)
34+
);
35+
}
36+
37+
public ComplexWaitStrategy with(WaitStrategy waitStrategy) {
38+
this.waitStrategyList.add(waitStrategy);
39+
return this;
40+
}
41+
}

core/src/main/java/org/testcontainers/containers/wait/experimental/MultiLogMessageWaitStrategy.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ protected String timeoutErrorMessage() {
5151
}
5252

5353
public MultiLogMessageWaitStrategy withRegex(String... regEx) {
54-
// TODO, add validation that we have at least one regex. :-)
5554
this.regEx = new LinkedBlockingDeque<>(Arrays.asList(regEx));
5655
return this;
5756
}

modules/postgresql/src/main/java/org/testcontainers/containers/PostgreSQLContainer.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package org.testcontainers.containers;
22

33
import org.jetbrains.annotations.NotNull;
4+
import org.testcontainers.containers.wait.experimental.ComplexWaitStrategy;
5+
import org.testcontainers.containers.wait.experimental.MultiLogMessageWaitStrategy;
46
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
57
import org.testcontainers.utility.DockerImageName;
68

@@ -49,10 +51,16 @@ public PostgreSQLContainer(final DockerImageName dockerImageName) {
4951
dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
5052

5153
this.waitStrategy =
52-
new LogMessageWaitStrategy()
53-
.withRegEx(".*database system is ready to accept connections.*\\s")
54-
.withTimes(2)
55-
.withStartupTimeout(Duration.of(60, ChronoUnit.SECONDS));
54+
new ComplexWaitStrategy()
55+
.with(new LogMessageWaitStrategy()
56+
.withRegEx(".*database system is ready to accept connections.*\\s")
57+
.withTimes(2)
58+
.withStartupTimeout(Duration.of(60, ChronoUnit.SECONDS)))
59+
.with(new MultiLogMessageWaitStrategy()
60+
.withRegex(".*PostgreSQL Database directory appears to contain a database; Skipping initialization.*",
61+
".*database system is ready to accept connections.*\\s")
62+
.withStartupTimeout(Duration.of(60, ChronoUnit.SECONDS)))
63+
;
5664
this.setCommand("postgres", "-c", FSYNC_OFF_OPTION);
5765

5866
addExposedPort(POSTGRESQL_PORT);

modules/postgresql/src/test/java/org/testcontainers/junit/postgresql/SimplePostgreSQLTest.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
import org.testcontainers.PostgreSQLTestImages;
55
import org.testcontainers.containers.PostgreSQLContainer;
66
import org.testcontainers.db.AbstractContainerDatabaseTest;
7+
import org.testcontainers.utility.DockerImageName;
78

89
import java.sql.ResultSet;
910
import java.sql.SQLException;
1011
import java.util.logging.Level;
1112
import java.util.logging.LogManager;
1213

1314
import static org.assertj.core.api.Assertions.assertThat;
15+
import static org.junit.Assert.assertEquals;
1416

1517
public class SimplePostgreSQLTest extends AbstractContainerDatabaseTest {
1618
static {
@@ -20,7 +22,23 @@ public class SimplePostgreSQLTest extends AbstractContainerDatabaseTest {
2022

2123
@Test
2224
public void testSimple() throws SQLException {
23-
try (PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(PostgreSQLTestImages.POSTGRES_TEST_IMAGE)) {
25+
try (PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(DockerImageName.parse("postgres:14"))) {
26+
postgres.start();
27+
28+
ResultSet resultSet = performQuery(postgres, "SELECT 1");
29+
int resultSetInt = resultSet.getInt(1);
30+
assertEquals("A basic SELECT query succeeds", 1, resultSetInt);
31+
}
32+
}
33+
34+
@Test
35+
public void testSimpleWithData() throws SQLException {
36+
DockerImageName IMAGE = DockerImageName.parse("tomcools/postgres:main")
37+
.asCompatibleSubstituteFor("postgres");
38+
try (PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(IMAGE)
39+
.withDatabaseName("testcontainer")
40+
.withUsername("sa")
41+
.withPassword("sa")) {
2442
postgres.start();
2543

2644
ResultSet resultSet = performQuery(postgres, "SELECT 1");

0 commit comments

Comments
 (0)