Skip to content

Commit

Permalink
Create a Complex Wait Strategy and include it in the PostgreSQLContainer
Browse files Browse the repository at this point in the history
  • Loading branch information
TomCools committed Jul 17, 2023
1 parent bdd1aed commit 58ae898
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.testcontainers.containers.wait.experimental;

import org.rnorth.ducttape.unreliables.Unreliables;
import org.testcontainers.containers.output.WaitingConsumer;
import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy;
import org.testcontainers.containers.wait.strategy.WaitStrategy;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


public class ComplexWaitStrategy extends AbstractWaitStrategy {

private final List<WaitStrategy> waitStrategyList = new ArrayList<>();

@Override
protected void waitUntilReady() {
ExecutorService service = Executors.newFixedThreadPool(waitStrategyList.size());
List<? extends Future<?>> futures = waitStrategyList.stream()
.map(waitStrategy -> service.submit(() -> waitStrategy.waitUntilReady(waitStrategyTarget)))
.collect(Collectors.toList());

Unreliables.retryUntilTrue(
(int) startupTimeout.getSeconds(),
TimeUnit.SECONDS,
() -> futures.stream().anyMatch(Future::isDone)
);
}

public ComplexWaitStrategy with(WaitStrategy waitStrategy) {
this.waitStrategyList.add(waitStrategy);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ protected String timeoutErrorMessage() {
}

public MultiLogMessageWaitStrategy withRegex(String... regEx) {
// TODO, add validation that we have at least one regex. :-)
this.regEx = new LinkedBlockingDeque<>(Arrays.asList(regEx));
return this;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.testcontainers.containers;

import org.jetbrains.annotations.NotNull;
import org.testcontainers.containers.wait.experimental.ComplexWaitStrategy;
import org.testcontainers.containers.wait.experimental.MultiLogMessageWaitStrategy;
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
import org.testcontainers.utility.DockerImageName;

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

this.waitStrategy =
new LogMessageWaitStrategy()
.withRegEx(".*database system is ready to accept connections.*\\s")
.withTimes(2)
.withStartupTimeout(Duration.of(60, ChronoUnit.SECONDS));
new ComplexWaitStrategy()
.with(new LogMessageWaitStrategy()
.withRegEx(".*database system is ready to accept connections.*\\s")
.withTimes(2)
.withStartupTimeout(Duration.of(60, ChronoUnit.SECONDS)))
.with(new MultiLogMessageWaitStrategy()
.withRegex(".*PostgreSQL Database directory appears to contain a database; Skipping initialization.*",
".*database system is ready to accept connections.*\\s")
.withStartupTimeout(Duration.of(60, ChronoUnit.SECONDS)))
;
this.setCommand("postgres", "-c", FSYNC_OFF_OPTION);

addExposedPort(POSTGRESQL_PORT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
import org.testcontainers.PostgreSQLTestImages;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.db.AbstractContainerDatabaseTest;
import org.testcontainers.utility.DockerImageName;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.LogManager;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;

public class SimplePostgreSQLTest extends AbstractContainerDatabaseTest {
static {
Expand All @@ -20,7 +22,23 @@ public class SimplePostgreSQLTest extends AbstractContainerDatabaseTest {

@Test
public void testSimple() throws SQLException {
try (PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(PostgreSQLTestImages.POSTGRES_TEST_IMAGE)) {
try (PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(DockerImageName.parse("postgres:14"))) {
postgres.start();

ResultSet resultSet = performQuery(postgres, "SELECT 1");
int resultSetInt = resultSet.getInt(1);
assertEquals("A basic SELECT query succeeds", 1, resultSetInt);
}
}

@Test
public void testSimpleWithData() throws SQLException {
DockerImageName IMAGE = DockerImageName.parse("tomcools/postgres:main")
.asCompatibleSubstituteFor("postgres");
try (PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(IMAGE)
.withDatabaseName("testcontainer")
.withUsername("sa")
.withPassword("sa")) {
postgres.start();

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

0 comments on commit 58ae898

Please sign in to comment.