Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make outer maximum startup timeout in DockerComposeContainer configurable #5588

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -103,6 +103,8 @@ public class DockerComposeContainer<SELF extends DockerComposeContainer<SELF>>

private final Map<String, WaitAllStrategy> waitStrategyMap = new ConcurrentHashMap<>();

private Duration startupTimeout = Duration.ofMinutes(30);

private final SocatContainer ambassadorContainer = new SocatContainer();

private final Map<String, List<Consumer<OutputFrame>>> logConsumers = new ConcurrentHashMap<>();
Expand Down Expand Up @@ -433,14 +435,14 @@ private String getServiceInstanceName(String serviceName) {
/*
* can have multiple wait strategies for a single container, e.g. if waiting on several ports
* if no wait strategy is defined, the WaitAllStrategy will return immediately.
* The WaitAllStrategy uses an long timeout, because timeouts should be handled by the inner strategies.
* The WaitAllStrategy uses the startup timeout for everything as a global maximum, but we expect timeouts to be handled by the inner strategies.
*/
private void addWaitStrategy(String serviceInstanceName, @NonNull WaitStrategy waitStrategy) {
final WaitAllStrategy waitAllStrategy = waitStrategyMap.computeIfAbsent(
serviceInstanceName,
__ -> {
return new WaitAllStrategy(WaitAllStrategy.Mode.WITH_MAXIMUM_OUTER_TIMEOUT)
.withStartupTimeout(Duration.ofMinutes(30));
.withStartupTimeout(startupTimeout);
}
);
waitAllStrategy.withStrategy(waitStrategy);
Expand Down Expand Up @@ -598,6 +600,16 @@ public SELF withRemoveImages(RemoveImages removeImages) {
return self();
}

/**
* Set the maximum startup timeout all the waits set are bounded to.
*
* @return this instance. for chaining
*/
public SELF withStartupTimeout(Duration startupTimeout) {
this.startupTimeout = startupTimeout;
return self();
}

public Optional<ContainerState> getContainerByServiceName(String serviceName) {
return Optional.ofNullable(serviceInstanceMap.get(serviceName));
}
Expand Down
@@ -1,12 +1,15 @@
package org.testcontainers.containers;

import org.junit.Test;
import org.testcontainers.containers.wait.strategy.Wait;

import java.io.File;
import java.time.Duration;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.rnorth.visibleassertions.VisibleAssertions.assertThrows;
import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals;

public class DockerComposeContainerWithServicesTest {
Expand Down Expand Up @@ -87,6 +90,21 @@ public void testScaleInComposeFileIsRespected() {
}
}

@Test
public void testStartupTimeoutSetsTheHighestTimeout() {
assertThrows("We expect a timeout from the startup timeout", org.rnorth.ducttape.TimeoutException.class,
() -> {
try (
DockerComposeContainer<?> compose = new DockerComposeContainer<>(SIMPLE_COMPOSE_FILE)
.withServices("redis")
.withStartupTimeout(Duration.ofMillis(1))
.withExposedService("redis", 80, Wait.forListeningPort().withStartupTimeout(Duration.ofMinutes(1)));
) {
compose.start();
}
});
}

private void verifyStartedContainers(final DockerComposeContainer<?> compose, final String... names) {
final List<String> containerNames = compose
.listChildContainers()
Expand Down