|
3 | 3 | import org.junit.Test; |
4 | 4 | import org.testcontainers.utility.ducttape.Timeouts; |
5 | 5 |
|
6 | | -import java.util.concurrent.RejectedExecutionException; |
7 | 6 | import java.util.concurrent.TimeUnit; |
8 | 7 |
|
9 | 8 | import static org.assertj.core.api.Assertions.assertThat; |
10 | | -import static org.assertj.core.api.Assertions.assertThatThrownBy; |
11 | 9 |
|
12 | 10 | /** |
13 | | - * POC demonstrating the bug in this PR's approach. |
14 | | - * |
15 | | - * <p>The PR adds {@code Timeouts.shutdown()} (which calls {@code EXECUTOR_SERVICE.shutdown()}) |
16 | | - * and invokes it from {@code GenericContainer.stop()}. Since {@code EXECUTOR_SERVICE} is a |
17 | | - * static final field shared across all callers, shutting it down after stopping one container |
18 | | - * permanently breaks all subsequent Timeouts usage — including wait strategies, startup checks, |
19 | | - * and {@code Unreliables.retryUntilSuccess} for any container started afterwards.</p> |
20 | | - * |
21 | | - * <p><b>Note:</b> This test intentionally shuts down the shared Timeouts executor, which is |
22 | | - * an irreversible operation within a single JVM. It should be run in its own Gradle test worker |
23 | | - * (e.g. via {@code --tests} filter) to avoid affecting other tests.</p> |
| 11 | + * Verifies that {@link Timeouts} works correctly across shutdown/reuse cycles. |
| 12 | + * After {@code shutdown()} the executor is re-created on next use. |
24 | 13 | */ |
25 | | -public class TimeoutsShutdownBugTest { |
| 14 | +public class TimeoutsShutdownTest { |
26 | 15 |
|
27 | | - /** |
28 | | - * Calls {@code Timeouts.shutdown()} (as {@code GenericContainer.stop()} does), then |
29 | | - * proves that subsequent Timeouts calls fail with {@link RejectedExecutionException}. |
30 | | - */ |
31 | 16 | @Test |
32 | | - public void shutdownBreaksSubsequentTimeoutCalls() { |
33 | | - // First call works fine — represents a container's wait strategy completing successfully |
| 17 | + public void timeoutsWorkAfterShutdown() { |
| 18 | + // First use |
34 | 19 | String result1 = Timeouts.getWithTimeout(5, TimeUnit.SECONDS, () -> "container-1-ready"); |
35 | 20 | assertThat(result1).isEqualTo("container-1-ready"); |
36 | 21 |
|
37 | | - // This is what GenericContainer.stop() does after stopping a container |
| 22 | + // Shutdown (as GenericContainer.stop() does) |
38 | 23 | Timeouts.shutdown(); |
39 | 24 |
|
40 | | - // Second call — represents starting another container after the first was stopped. |
41 | | - // This fails because the static shared executor rejects new tasks after shutdown. |
42 | | - assertThatThrownBy(() -> Timeouts.getWithTimeout(5, TimeUnit.SECONDS, () -> "container-2-ready")) |
43 | | - .isInstanceOf(RejectedExecutionException.class); |
| 25 | + // Second use — should transparently create a fresh executor |
| 26 | + String result2 = Timeouts.getWithTimeout(5, TimeUnit.SECONDS, () -> "container-2-ready"); |
| 27 | + assertThat(result2).isEqualTo("container-2-ready"); |
| 28 | + |
| 29 | + // Shutdown and use again to confirm repeatable |
| 30 | + Timeouts.shutdown(); |
| 31 | + |
| 32 | + String result3 = Timeouts.getWithTimeout(5, TimeUnit.SECONDS, () -> "container-3-ready"); |
| 33 | + assertThat(result3).isEqualTo("container-3-ready"); |
44 | 34 | } |
45 | 35 | } |
0 commit comments