Skip to content

Commit 95c828d

Browse files
bsideupByron Daviddbyron0
authored
Include image name in RemoteDockerImage#toString (#2558)
* clean up imports in GenericContainer * include image name in RemoteDockerImage.toString() to fix #2443 * test RemoteDockerImage directly * handle failures getting the image name * use completeExceptionally instead of mocking * tweak assertions * more assertion tweaks * add isDone check to RemoteDockerImage.toString -- still figuring out why test fails * go back to using lombok @tostring, exclude dockerClient while we're at it * use `Futures.lazyTransform` that also proxies `isDone` * `imageNameToString` should not be public * Include the message on error Co-authored-by: Byron David <[email protected]> Co-authored-by: David Byron <[email protected]>
1 parent 34b8d7e commit 95c828d

File tree

3 files changed

+69
-9
lines changed

3 files changed

+69
-9
lines changed

core/src/main/java/org/testcontainers/images/RemoteDockerImage.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.github.dockerjava.api.DockerClient;
44
import com.github.dockerjava.api.exception.DockerClientException;
55
import com.github.dockerjava.api.exception.InternalServerErrorException;
6+
import com.google.common.util.concurrent.Futures;
67
import lombok.AccessLevel;
78
import lombok.AllArgsConstructor;
89
import lombok.NonNull;
@@ -28,11 +29,13 @@ public class RemoteDockerImage extends LazyFuture<String> {
2829

2930
private static final Duration PULL_RETRY_TIME_LIMIT = Duration.ofMinutes(2);
3031

32+
@ToString.Exclude
3133
private Future<DockerImageName> imageNameFuture;
3234

3335
@Wither
3436
private ImagePullPolicy imagePullPolicy = PullPolicy.defaultPolicy();
3537

38+
@ToString.Exclude
3639
private DockerClient dockerClient = DockerClientFactory.lazyClient();
3740

3841
public RemoteDockerImage(String dockerImageName) {
@@ -44,19 +47,13 @@ public RemoteDockerImage(@NonNull String repository, @NonNull String tag) {
4447
}
4548

4649
public RemoteDockerImage(@NonNull Future<String> imageFuture) {
47-
this.imageNameFuture = new LazyFuture<DockerImageName>() {
48-
@Override
49-
@SneakyThrows({InterruptedException.class, ExecutionException.class})
50-
protected DockerImageName resolve() {
51-
return new DockerImageName(imageFuture.get());
52-
}
53-
};
50+
this.imageNameFuture = Futures.lazyTransform(imageFuture, DockerImageName::new);
5451
}
5552

5653
@Override
5754
@SneakyThrows({InterruptedException.class, ExecutionException.class})
5855
protected final String resolve() {
59-
final DockerImageName imageName = imageNameFuture.get();
56+
final DockerImageName imageName = getImageName();
6057
Logger logger = DockerLoggerFactory.getLogger(imageName.toString());
6158
try {
6259
if (!imagePullPolicy.shouldPull(imageName)) {
@@ -95,4 +92,21 @@ protected final String resolve() {
9592
throw new ContainerFetchException("Failed to get Docker client for " + imageName, e);
9693
}
9794
}
95+
96+
private DockerImageName getImageName() throws InterruptedException, ExecutionException {
97+
return imageNameFuture.get();
98+
}
99+
100+
@ToString.Include(name = "imageName", rank = 1)
101+
private String imageNameToString() {
102+
if (!imageNameFuture.isDone()) {
103+
return "<resolving>";
104+
}
105+
106+
try {
107+
return getImageName().toString();
108+
} catch (InterruptedException | ExecutionException e) {
109+
return e.getMessage();
110+
}
111+
}
98112
}

core/src/test/java/org/testcontainers/containers/GenericContainerTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.github.dockerjava.api.DockerClient;
44
import com.github.dockerjava.api.command.InspectContainerResponse.ContainerState;
5-
import com.github.dockerjava.api.model.HostConfig;
65
import lombok.RequiredArgsConstructor;
76
import lombok.SneakyThrows;
87
import lombok.experimental.FieldDefaults;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.testcontainers.images;
2+
3+
import static org.hamcrest.CoreMatchers.containsString;
4+
import static org.junit.Assert.assertFalse;
5+
import static org.junit.Assert.assertThat;
6+
7+
import org.junit.Test;
8+
import org.testcontainers.utility.Base58;
9+
10+
import java.util.concurrent.CompletableFuture;
11+
12+
public class RemoteDockerImageTest {
13+
14+
@Test
15+
public void toStringContainsOnlyImageName() {
16+
String imageName = Base58.randomString(8).toLowerCase();
17+
RemoteDockerImage remoteDockerImage = new RemoteDockerImage(imageName);
18+
assertThat(remoteDockerImage.toString(), containsString("imageName=" + imageName));
19+
}
20+
21+
@Test
22+
public void toStringWithExceptionContainsOnlyImageNameFuture() {
23+
CompletableFuture<String> imageNameFuture = new CompletableFuture<>();
24+
imageNameFuture.completeExceptionally(new RuntimeException("arbitrary"));
25+
26+
RemoteDockerImage remoteDockerImage = new RemoteDockerImage(imageNameFuture);
27+
assertThat(remoteDockerImage.toString(), containsString("imageName=java.lang.RuntimeException: arbitrary"));
28+
}
29+
30+
@Test(timeout=5000L)
31+
public void toStringDoesntResolveImageNameFuture() {
32+
CompletableFuture<String> imageNameFuture = new CompletableFuture<>();
33+
34+
// verify that we've set up the test properly
35+
assertFalse(imageNameFuture.isDone());
36+
37+
RemoteDockerImage remoteDockerImage = new RemoteDockerImage(imageNameFuture);
38+
assertThat(remoteDockerImage.toString(), containsString("imageName=<resolving>"));
39+
40+
// Make sure the act of calling toString doesn't resolve the imageNameFuture
41+
assertFalse(imageNameFuture.isDone());
42+
43+
String imageName = Base58.randomString(8).toLowerCase();
44+
imageNameFuture.complete(imageName);
45+
assertThat(remoteDockerImage.toString(), containsString("imageName=" + imageName));
46+
}
47+
}

0 commit comments

Comments
 (0)