diff --git a/core/src/main/java/org/testcontainers/containers/wait/strategy/WaitAllStrategy.java b/core/src/main/java/org/testcontainers/containers/wait/strategy/WaitAllStrategy.java index 5c7530fc67f..ca32e5ba4a2 100644 --- a/core/src/main/java/org/testcontainers/containers/wait/strategy/WaitAllStrategy.java +++ b/core/src/main/java/org/testcontainers/containers/wait/strategy/WaitAllStrategy.java @@ -88,7 +88,9 @@ public WaitAllStrategy withStartupTimeout(Duration startupTimeout) { } this.timeout = startupTimeout; - strategies.forEach(this::applyStartupTimeout); + if (mode == Mode.WITH_OUTER_TIMEOUT) { + strategies.forEach(this::applyStartupTimeout); + } return this; } diff --git a/core/src/test/java/org/testcontainers/containers/wait/strategy/WaitAllStrategyTest.java b/core/src/test/java/org/testcontainers/containers/wait/strategy/WaitAllStrategyTest.java index aeebe425776..7fdaa18e625 100644 --- a/core/src/test/java/org/testcontainers/containers/wait/strategy/WaitAllStrategyTest.java +++ b/core/src/test/java/org/testcontainers/containers/wait/strategy/WaitAllStrategyTest.java @@ -11,6 +11,7 @@ import java.time.Duration; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.catchThrowable; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -90,6 +91,61 @@ void parentTimeoutAppliesToAdditionalChildren() { .isEqualTo(20L); } + @Test + void maximumOuterTimeoutPreservesChildrenAddedAfterTimeout() { + DummyStrategy child1 = new DummyStrategy(Duration.ofSeconds(5)); + DummyStrategy child2 = new DummyStrategy(Duration.ofSeconds(10)); + + new WaitAllStrategy(WaitAllStrategy.Mode.WITH_MAXIMUM_OUTER_TIMEOUT) + .withStartupTimeout(Duration.ofSeconds(60)) + .withStrategy(child1) + .withStrategy(child2); + + assertThat(child1.startupTimeout).isEqualTo(Duration.ofSeconds(5)); + assertThat(child2.startupTimeout).isEqualTo(Duration.ofSeconds(10)); + } + + @Test + void maximumOuterTimeoutPreservesChildrenAddedBeforeTimeout() { + DummyStrategy child1 = new DummyStrategy(Duration.ofSeconds(5)); + DummyStrategy child2 = new DummyStrategy(Duration.ofSeconds(10)); + + new WaitAllStrategy(WaitAllStrategy.Mode.WITH_MAXIMUM_OUTER_TIMEOUT) + .withStrategy(child1) + .withStrategy(child2) + .withStartupTimeout(Duration.ofSeconds(60)); + + assertThat(child1.startupTimeout).isEqualTo(Duration.ofSeconds(5)); + assertThat(child2.startupTimeout).isEqualTo(Duration.ofSeconds(10)); + } + + @Test + void maximumOuterTimeoutPreservesChildrenWhenTimeoutChanges() { + DummyStrategy child1 = new DummyStrategy(Duration.ofSeconds(5)); + DummyStrategy child2 = new DummyStrategy(Duration.ofSeconds(10)); + + new WaitAllStrategy(WaitAllStrategy.Mode.WITH_MAXIMUM_OUTER_TIMEOUT) + .withStrategy(child1) + .withStartupTimeout(Duration.ofSeconds(60)) + .withStrategy(child2) + .withStartupTimeout(Duration.ofSeconds(90)); + + assertThat(child1.startupTimeout).isEqualTo(Duration.ofSeconds(5)); + assertThat(child2.startupTimeout).isEqualTo(Duration.ofSeconds(10)); + } + + @Test + void maximumOuterTimeoutAllowsNestedIndividualTimeoutStrategy() { + WaitAllStrategy child = new WaitAllStrategy(WaitAllStrategy.Mode.WITH_INDIVIDUAL_TIMEOUTS_ONLY); + + assertThatCode(() -> { + new WaitAllStrategy(WaitAllStrategy.Mode.WITH_MAXIMUM_OUTER_TIMEOUT) + .withStrategy(child) + .withStartupTimeout(Duration.ofSeconds(60)); + }) + .doesNotThrowAnyException(); + } + /* * Mock-based tests to check overall behaviour, without involving timing-sensitive code */