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

Image name in remote docker image to string #2450

Expand Up @@ -26,9 +26,6 @@
import lombok.NonNull;
import lombok.Setter;
import lombok.SneakyThrows;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
Expand All @@ -42,7 +39,6 @@
import org.slf4j.Logger;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.UnstableAPI;
import org.testcontainers.images.ImagePullPolicy;
import org.testcontainers.containers.output.OutputFrame;
import org.testcontainers.containers.startupcheck.IsRunningStartupCheckStrategy;
import org.testcontainers.containers.startupcheck.MinimumDurationRunningStartupCheckStrategy;
Expand All @@ -51,8 +47,8 @@
import org.testcontainers.containers.wait.Wait;
import org.testcontainers.containers.wait.WaitStrategy;
import org.testcontainers.containers.wait.strategy.WaitStrategyTarget;
import org.testcontainers.images.ImagePullPolicy;
import org.testcontainers.images.RemoteDockerImage;
import org.testcontainers.images.builder.Transferable;
import org.testcontainers.lifecycle.Startable;
import org.testcontainers.lifecycle.Startables;
import org.testcontainers.lifecycle.TestDescription;
Expand All @@ -64,14 +60,9 @@
import org.testcontainers.utility.PathUtils;
import org.testcontainers.utility.ResourceReaper;
import org.testcontainers.utility.TestcontainersConfiguration;
import org.testcontainers.utility.ThrowingFunction;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
Expand Down
Expand Up @@ -3,6 +3,7 @@
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.exception.DockerClientException;
import com.github.dockerjava.api.exception.InternalServerErrorException;
import com.google.common.base.MoreObjects;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NonNull;
Expand All @@ -28,11 +29,13 @@ public class RemoteDockerImage extends LazyFuture<String> {

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

@ToString.Exclude
private Future<DockerImageName> imageNameFuture;

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

@ToString.Exclude
private DockerClient dockerClient = DockerClientFactory.lazyClient();

public RemoteDockerImage(String dockerImageName) {
Expand All @@ -56,7 +59,7 @@ protected DockerImageName resolve() {
@Override
@SneakyThrows({InterruptedException.class, ExecutionException.class})
protected final String resolve() {
final DockerImageName imageName = imageNameFuture.get();
final DockerImageName imageName = getImageName();
Logger logger = DockerLoggerFactory.getLogger(imageName.toString());
try {
if (!imagePullPolicy.shouldPull(imageName)) {
Expand Down Expand Up @@ -95,4 +98,26 @@ protected final String resolve() {
throw new ContainerFetchException("Failed to get Docker client for " + imageName, e);
}
}

DockerImageName getImageName() throws InterruptedException, ExecutionException {
return imageNameFuture.get();
}

@ToString.Include(name = "imageName", rank = 1)
public String imageNameToString() {
// Include the imageName if it's available
DockerImageName imageName = null;
if (imageNameFuture.isDone()) {
try {
return getImageName().toString();
} catch (InterruptedException | ExecutionException e) {
// Swallow this exception and use imageNameFuture instead.
// Don't log this, as the whole struggle here is that we don't know
// the image name, and DockerLoggerFactory.getLogger takes an image
// name argument.
}
}

return imageNameFuture.toString();
}
}
Expand Up @@ -2,7 +2,6 @@

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.InspectContainerResponse.ContainerState;
import com.github.dockerjava.api.model.HostConfig;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.experimental.FieldDefaults;
Expand Down
@@ -0,0 +1,43 @@
package org.testcontainers.images;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;

import org.junit.Test;
import org.testcontainers.utility.Base58;

import java.util.concurrent.CompletableFuture;

public class RemoteDockerImageTest {

@Test
public void toStringContainsOnlyImageName() {
String imageName = Base58.randomString(8).toLowerCase();
RemoteDockerImage remoteDockerImage = new RemoteDockerImage(imageName);
String toString = remoteDockerImage.toString();
assertThat(toString, containsString("imageName=" + imageName));
}

@Test
public void toStringWithExceptionContainsOnlyImageNameFuture() {
CompletableFuture<String> imageNameFuture = new CompletableFuture<>();
imageNameFuture.completeExceptionally(new RuntimeException("arbitrary"));
RemoteDockerImage remoteDockerImage = new RemoteDockerImage(imageNameFuture);
String toString = remoteDockerImage.toString();
assertThat(toString, containsString("imageName=" + RemoteDockerImage.class.getName()));
}

@Test(timeout=5000L)
public void toStringDoesntResolveImageNameFuture() {
CompletableFuture<String> imageNameFuture = new CompletableFuture<>();
// verify that we've set up the test properly
assertFalse(imageNameFuture.isDone());
RemoteDockerImage remoteDockerImage = new RemoteDockerImage(imageNameFuture);
String toString = remoteDockerImage.toString();
assertThat(toString, containsString("imageName=" + RemoteDockerImage.class.getName()));
// Make sure the act of calling toString doesn't resolve the imageNameFuture
assertFalse(imageNameFuture.isDone());
}
}