diff --git a/core/src/main/java/org/testcontainers/utility/LazyFuture.java b/core/src/main/java/org/testcontainers/utility/LazyFuture.java
index b0aa4346cbb..758082f5185 100644
--- a/core/src/main/java/org/testcontainers/utility/LazyFuture.java
+++ b/core/src/main/java/org/testcontainers/utility/LazyFuture.java
@@ -2,10 +2,10 @@
import lombok.AccessLevel;
import lombok.Getter;
-import lombok.experimental.Delegate;
import org.rnorth.ducttape.timeouts.Timeouts;
import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicReference;
/**
* Future implementation with lazy result evaluation in the same Thread as caller.
@@ -14,31 +14,37 @@
*/
public abstract class LazyFuture implements Future {
- @Delegate(excludes = Excludes.class)
- private final Future delegate = CompletableFuture.completedFuture(null);
-
@Getter(value = AccessLevel.MODULE, lazy = true)
private final T resolvedValue = resolve();
abstract protected T resolve();
@Override
- public T get() throws InterruptedException, ExecutionException {
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ return false;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return false;
+ }
+
+ @Override
+ public boolean isDone() {
+ return ((AtomicReference>) resolvedValue).get() != null;
+ }
+
+ @Override
+ public T get() {
return getResolvedValue();
}
@Override
- public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+ public T get(long timeout, TimeUnit unit) throws TimeoutException {
try {
return Timeouts.getWithTimeout((int) timeout, unit, this::get);
} catch (org.rnorth.ducttape.TimeoutException e) {
throw new TimeoutException(e.getMessage());
}
}
-
- private interface Excludes {
- T get();
-
- T get(long timeout, TimeUnit unit);
- }
}
diff --git a/core/src/test/java/org/testcontainers/images/RemoteDockerImageTest.java b/core/src/test/java/org/testcontainers/images/RemoteDockerImageTest.java
index c62f15653b3..6b6a82559bf 100644
--- a/core/src/test/java/org/testcontainers/images/RemoteDockerImageTest.java
+++ b/core/src/test/java/org/testcontainers/images/RemoteDockerImageTest.java
@@ -6,8 +6,11 @@
import org.junit.Test;
import org.testcontainers.utility.Base58;
+import org.testcontainers.utility.LazyFuture;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicBoolean;
public class RemoteDockerImageTest {
@@ -44,4 +47,31 @@ public void toStringDoesntResolveImageNameFuture() {
imageNameFuture.complete(imageName);
assertThat(remoteDockerImage.toString(), containsString("imageName=" + imageName));
}
+
+ @Test(timeout=5000L)
+ public void toStringDoesntResolveLazyFuture() throws Exception {
+ String imageName = Base58.randomString(8).toLowerCase();
+ AtomicBoolean resolved = new AtomicBoolean(false);
+ Future imageNameFuture = new LazyFuture() {
+ @Override
+ protected String resolve() {
+ resolved.set(true);
+ return imageName;
+ }
+ };
+
+ // verify that we've set up the test properly
+ assertFalse(imageNameFuture.isDone());
+
+ RemoteDockerImage remoteDockerImage = new RemoteDockerImage(imageNameFuture);
+ assertThat(remoteDockerImage.toString(), containsString("imageName="));
+
+ // Make sure the act of calling toString doesn't resolve the imageNameFuture
+ assertFalse(imageNameFuture.isDone());
+ assertFalse(resolved.get());
+
+ // Trigger resolve
+ imageNameFuture.get();
+ assertThat(remoteDockerImage.toString(), containsString("imageName=" + imageName));
+ }
}