From d7e259d261b9b21d551c21b023385316fd0eefe7 Mon Sep 17 00:00:00 2001 From: Grzegorz Piwowarek Date: Sat, 2 Nov 2019 13:02:12 +0200 Subject: [PATCH 1/3] Reduce Guava usage --- .../testcontainers/DockerClientFactory.java | 22 ++++++++++++------- .../containers/output/OutputFrame.java | 5 +++-- .../containers/output/ToStringConsumer.java | 5 ++--- .../images/builder/ImageFromDockerfile.java | 3 --- .../utility/LicenseAcceptance.java | 4 ++-- .../testcontainers/utility/MountableFile.java | 4 ++-- .../utility/ResourceReaper.java | 14 +++++++----- 7 files changed, 31 insertions(+), 26 deletions(-) diff --git a/core/src/main/java/org/testcontainers/DockerClientFactory.java b/core/src/main/java/org/testcontainers/DockerClientFactory.java index 928b4cad291..81678c92f1b 100644 --- a/core/src/main/java/org/testcontainers/DockerClientFactory.java +++ b/core/src/main/java/org/testcontainers/DockerClientFactory.java @@ -12,7 +12,6 @@ import com.github.dockerjava.api.model.Volume; import com.github.dockerjava.core.command.ExecStartResultCallback; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableMap; import lombok.Getter; import lombok.SneakyThrows; import lombok.Synchronized; @@ -31,6 +30,8 @@ import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -53,20 +54,17 @@ public class DockerClientFactory { public static final String SESSION_ID = UUID.randomUUID().toString(); - public static final Map DEFAULT_LABELS = ImmutableMap.of( - TESTCONTAINERS_LABEL, "true", - TESTCONTAINERS_SESSION_ID_LABEL, SESSION_ID - ); + public static final Map DEFAULT_LABELS = defaultLabels(); private static final String TINY_IMAGE = TestcontainersConfiguration.getInstance().getTinyImage(); - private static DockerClientFactory instance; + private static DockerClientFactory instance; // Cached client configuration + private DockerClientProviderStrategy strategy; private boolean initialized = false; private String activeApiVersion; private String activeExecutionDriver; - @Getter(lazy = true) private final boolean fileMountingSupported = checkMountableFile(); @@ -265,10 +263,10 @@ private T runInsideDocker(DockerClient client, Consumer @VisibleForTesting static class DiskSpaceUsage { + Optional availableMB = Optional.empty(); Optional usedPercent = Optional.empty(); } - @VisibleForTesting DiskSpaceUsage parseAvailableDiskSpace(String dfOutput) { DiskSpaceUsage df = new DiskSpaceUsage(); @@ -314,8 +312,16 @@ public boolean isUsing(Class providerStr } private static class NotEnoughDiskSpaceException extends RuntimeException { + NotEnoughDiskSpaceException(String message) { super(message); } } + + private static Map defaultLabels() { + Map map = new HashMap<>(); + map.put(TESTCONTAINERS_LABEL, "true"); + map.put(TESTCONTAINERS_SESSION_ID_LABEL, SESSION_ID); + return Collections.unmodifiableMap(map); + } } diff --git a/core/src/main/java/org/testcontainers/containers/output/OutputFrame.java b/core/src/main/java/org/testcontainers/containers/output/OutputFrame.java index d5ddcada8c8..e19473ef982 100644 --- a/core/src/main/java/org/testcontainers/containers/output/OutputFrame.java +++ b/core/src/main/java/org/testcontainers/containers/output/OutputFrame.java @@ -2,7 +2,8 @@ import com.github.dockerjava.api.model.Frame; import com.github.dockerjava.api.model.StreamType; -import com.google.common.base.Charsets; + +import java.nio.charset.StandardCharsets; /** * Holds a frame of container output (usually one line, possibly more) @@ -33,7 +34,7 @@ public String getUtf8String() { return ""; } - return new String(bytes, Charsets.UTF_8); + return new String(bytes, StandardCharsets.UTF_8); } public enum OutputType { diff --git a/core/src/main/java/org/testcontainers/containers/output/ToStringConsumer.java b/core/src/main/java/org/testcontainers/containers/output/ToStringConsumer.java index a12325865aa..772f7addc02 100644 --- a/core/src/main/java/org/testcontainers/containers/output/ToStringConsumer.java +++ b/core/src/main/java/org/testcontainers/containers/output/ToStringConsumer.java @@ -1,10 +1,9 @@ package org.testcontainers.containers.output; -import com.google.common.base.Charsets; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; /** * Created by rnorth on 26/03/2016. @@ -33,7 +32,7 @@ public void accept(OutputFrame outputFrame) { public String toUtf8String() { byte[] bytes = stringBuffer.toByteArray(); - return new String(bytes, Charsets.UTF_8); + return new String(bytes, StandardCharsets.UTF_8); } public String toString(Charset charset) { diff --git a/core/src/main/java/org/testcontainers/images/builder/ImageFromDockerfile.java b/core/src/main/java/org/testcontainers/images/builder/ImageFromDockerfile.java index 98d0dda5e5c..221e81638c6 100644 --- a/core/src/main/java/org/testcontainers/images/builder/ImageFromDockerfile.java +++ b/core/src/main/java/org/testcontainers/images/builder/ImageFromDockerfile.java @@ -2,10 +2,8 @@ import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.command.BuildImageCmd; -import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.api.model.BuildResponseItem; import com.github.dockerjava.core.command.BuildImageResultCallback; -import com.google.common.collect.Sets; import lombok.Cleanup; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -31,7 +29,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; -import java.util.Set; import java.util.zip.GZIPOutputStream; @Slf4j diff --git a/core/src/main/java/org/testcontainers/utility/LicenseAcceptance.java b/core/src/main/java/org/testcontainers/utility/LicenseAcceptance.java index 55037d8978c..b525a0af973 100644 --- a/core/src/main/java/org/testcontainers/utility/LicenseAcceptance.java +++ b/core/src/main/java/org/testcontainers/utility/LicenseAcceptance.java @@ -1,10 +1,10 @@ package org.testcontainers.utility; -import com.google.common.base.Charsets; import com.google.common.io.Resources; import lombok.experimental.UtilityClass; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.List; /** @@ -18,7 +18,7 @@ public class LicenseAcceptance { public static void assertLicenseAccepted(final String imageName) { try { final URL url = Resources.getResource(ACCEPTANCE_FILE_NAME); - final List acceptedLicences = Resources.readLines(url, Charsets.UTF_8); + final List acceptedLicences = Resources.readLines(url, StandardCharsets.UTF_8); if (acceptedLicences.stream().map(String::trim).anyMatch(imageName::equals)) { return; diff --git a/core/src/main/java/org/testcontainers/utility/MountableFile.java b/core/src/main/java/org/testcontainers/utility/MountableFile.java index 56d5bda3ffa..1e4f512dbae 100644 --- a/core/src/main/java/org/testcontainers/utility/MountableFile.java +++ b/core/src/main/java/org/testcontainers/utility/MountableFile.java @@ -1,6 +1,5 @@ package org.testcontainers.utility; -import com.google.common.base.Charsets; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -18,6 +17,7 @@ import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -148,7 +148,7 @@ private static URL getClasspathResource(@NotNull final String resourcePath, @Not private static String unencodeResourceURIToFilePath(@NotNull final String resource) { try { // Convert any url-encoded characters (e.g. spaces) back into unencoded form - return URLDecoder.decode(resource.replaceAll("\\+", "%2B"), Charsets.UTF_8.name()) + return URLDecoder.decode(resource.replaceAll("\\+", "%2B"), StandardCharsets.UTF_8.toString()) .replaceFirst("jar:", "") .replaceFirst("file:", "") .replaceAll("!.*", ""); diff --git a/core/src/main/java/org/testcontainers/utility/ResourceReaper.java b/core/src/main/java/org/testcontainers/utility/ResourceReaper.java index f46db952c37..32e3e4f0e3e 100644 --- a/core/src/main/java/org/testcontainers/utility/ResourceReaper.java +++ b/core/src/main/java/org/testcontainers/utility/ResourceReaper.java @@ -11,7 +11,6 @@ import com.github.dockerjava.api.model.Volume; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Throwables; -import com.google.common.collect.Sets; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -30,6 +29,7 @@ import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -40,6 +40,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import static java.util.Collections.synchronizedSet; + /** * Component that responsible for container removal and automatic cleanup of dead containers at JVM shutdown. */ @@ -52,9 +54,9 @@ public final class ResourceReaper { private static ResourceReaper instance; private final DockerClient dockerClient; - private Map registeredContainers = new ConcurrentHashMap<>(); - private Set registeredNetworks = Sets.newConcurrentHashSet(); - private Set registeredImages = Sets.newConcurrentHashSet(); + private final Map registeredContainers = new ConcurrentHashMap<>(); + private final Set registeredNetworks = synchronizedSet(new HashSet<>()); + private final Set registeredImages = synchronizedSet(new HashSet<>()); private AtomicBoolean hookIsSet = new AtomicBoolean(false); private ResourceReaper() { @@ -341,12 +343,12 @@ public void unregisterNetwork(String identifier) { public void unregisterContainer(String identifier) { registeredContainers.remove(identifier); } - + public void registerImageForCleanup(String dockerImageName) { setHook(); registeredImages.add(dockerImageName); } - + private void removeImage(String dockerImageName) { LOGGER.trace("Removing image tagged {}", dockerImageName); try { From d6d42ec90a750bfa04d897de13c0c7a00ee74517 Mon Sep 17 00:00:00 2001 From: Grzegorz Piwowarek Date: Sat, 2 Nov 2019 13:24:50 +0200 Subject: [PATCH 2/3] Reduce usage of Guava's tools --- .../containers/DockerComposeContainer.java | 30 +++++++++++++++---- .../containers/GenericContainer.java | 17 +++++++---- .../okhttp/OkHttpDockerCmdExecFactory.java | 6 ++-- .../transport/okhttp/OkHttpWebTarget.java | 20 ++++++------- 4 files changed, 49 insertions(+), 24 deletions(-) diff --git a/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java b/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java index b21e160d892..1be25cea2f8 100644 --- a/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java +++ b/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java @@ -5,7 +5,6 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; import com.google.common.base.Splitter; -import com.google.common.collect.Maps; import com.google.common.util.concurrent.Uninterruptibles; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; @@ -19,9 +18,18 @@ import org.testcontainers.containers.output.OutputFrame; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.containers.startupcheck.IndefiniteWaitOneShotStartupCheckStrategy; -import org.testcontainers.containers.wait.strategy.*; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.containers.wait.strategy.WaitAllStrategy; +import org.testcontainers.containers.wait.strategy.WaitStrategy; import org.testcontainers.lifecycle.Startable; -import org.testcontainers.utility.*; +import org.testcontainers.utility.AuditLogger; +import org.testcontainers.utility.Base58; +import org.testcontainers.utility.CommandLine; +import org.testcontainers.utility.DockerLoggerFactory; +import org.testcontainers.utility.LogUtils; +import org.testcontainers.utility.MountableFile; +import org.testcontainers.utility.ResourceReaper; +import org.testcontainers.utility.TestcontainersConfiguration; import org.yaml.snakeyaml.Yaml; import org.zeroturnaround.exec.InvalidExitValueException; import org.zeroturnaround.exec.ProcessExecutor; @@ -30,10 +38,20 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.nio.file.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.time.Duration; import java.util.AbstractMap.SimpleEntry; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -674,7 +692,7 @@ public void invoke() { throw new ContainerLaunchException("Local Docker Compose not found. Is " + COMPOSE_EXECUTABLE + " on the PATH?"); } - final Map environment = Maps.newHashMap(env); + final Map environment = new HashMap<>(env); environment.put(ENV_PROJECT_NAME, identifier); diff --git a/core/src/main/java/org/testcontainers/containers/GenericContainer.java b/core/src/main/java/org/testcontainers/containers/GenericContainer.java index f17e8dfd0b2..cd28d6df5dc 100644 --- a/core/src/main/java/org/testcontainers/containers/GenericContainer.java +++ b/core/src/main/java/org/testcontainers/containers/GenericContainer.java @@ -18,7 +18,6 @@ import com.github.dockerjava.api.model.VolumesFrom; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; -import com.google.common.collect.ImmutableMap; import lombok.AccessLevel; import lombok.Data; import lombok.NonNull; @@ -28,7 +27,6 @@ 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.lang.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.junit.runner.Description; @@ -71,6 +69,7 @@ import java.io.InputStream; import java.lang.reflect.Method; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.time.Duration; import java.time.Instant; @@ -93,7 +92,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import static com.google.common.collect.Lists.newArrayList; import static org.testcontainers.utility.CommandLine.runShellCommand; /** @@ -104,7 +102,7 @@ public class GenericContainer> extends FailureDetectingExternalResource implements Container, AutoCloseable, WaitStrategyTarget, Startable { - private static final Charset UTF8 = Charset.forName("UTF-8"); + private static final Charset UTF8 = StandardCharsets.UTF_8; public static final int CONTAINER_RUNNING_TIMEOUT_SEC = 30; @@ -435,7 +433,7 @@ final String hash(CreateContainerCmd createCommand) { Optional findContainerForReuse(String hash) { // TODO locking return dockerClient.listContainersCmd() - .withLabelFilter(ImmutableMap.of(HASH_LABEL, hash)) + .withLabelFilter(labelFilterFor(hash)) .withLimit(1) .withStatusFilter(Arrays.asList("running")) .exec() @@ -444,6 +442,13 @@ Optional findContainerForReuse(String hash) { .map(it -> it.getId()); } + @NotNull + private Map labelFilterFor(String hash) { + Map labels = new HashMap<>(); + labels.put(HASH_LABEL, hash); + return Collections.unmodifiableMap(labels); + } + /** * Set any custom settings for the create command such as shared memory size. */ @@ -926,7 +931,7 @@ protected void finished(Description description) { */ @Override public SELF withExposedPorts(Integer... ports) { - this.setExposedPorts(newArrayList(ports)); + this.setExposedPorts(new ArrayList<>(Arrays.asList(ports))); return self(); } diff --git a/core/src/main/java/org/testcontainers/dockerclient/transport/okhttp/OkHttpDockerCmdExecFactory.java b/core/src/main/java/org/testcontainers/dockerclient/transport/okhttp/OkHttpDockerCmdExecFactory.java index 841d012e2b3..ff747b8a115 100644 --- a/core/src/main/java/org/testcontainers/dockerclient/transport/okhttp/OkHttpDockerCmdExecFactory.java +++ b/core/src/main/java/org/testcontainers/dockerclient/transport/okhttp/OkHttpDockerCmdExecFactory.java @@ -6,7 +6,6 @@ import com.github.dockerjava.core.SSLConfig; import com.github.dockerjava.core.WebTarget; import com.github.dockerjava.core.exec.PingCmdExec; -import com.google.common.collect.ImmutableList; import com.google.common.collect.MultimapBuilder; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -22,9 +21,12 @@ import java.net.InetAddress; import java.net.URI; import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Collections; import java.util.concurrent.TimeUnit; +import static java.util.Collections.unmodifiableList; + @Slf4j public class OkHttpDockerCmdExecFactory extends AbstractDockerCmdExecFactory { @@ -107,7 +109,7 @@ protected WebTarget getBaseResource() { return new OkHttpWebTarget( okHttpClient, baseUrl, - ImmutableList.of(), + unmodifiableList(new ArrayList<>()), MultimapBuilder.hashKeys().hashSetValues().build() ); } diff --git a/core/src/main/java/org/testcontainers/dockerclient/transport/okhttp/OkHttpWebTarget.java b/core/src/main/java/org/testcontainers/dockerclient/transport/okhttp/OkHttpWebTarget.java index 7e12b0b4541..4f65b92b12c 100644 --- a/core/src/main/java/org/testcontainers/dockerclient/transport/okhttp/OkHttpWebTarget.java +++ b/core/src/main/java/org/testcontainers/dockerclient/transport/okhttp/OkHttpWebTarget.java @@ -6,7 +6,6 @@ import com.github.dockerjava.core.InvocationBuilder; import com.github.dockerjava.core.WebTarget; import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableList; import com.google.common.collect.SetMultimap; import lombok.SneakyThrows; import lombok.Value; @@ -15,7 +14,10 @@ import okhttp3.OkHttpClient; import org.apache.commons.lang.StringUtils; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -32,7 +34,7 @@ class OkHttpWebTarget implements WebTarget { HttpUrl baseUrl; - ImmutableList path; + List path; SetMultimap queryParams; @@ -64,22 +66,20 @@ public InvocationBuilder request() { @Override public OkHttpWebTarget path(String... components) { - return this.withPath( - ImmutableList.builder() - .addAll(path) - .add(components) - .build() - ); + List newPath = new ArrayList<>(path); + Collections.addAll(newPath, components); + + return this.withPath(Collections.unmodifiableList(newPath)); } @Override public OkHttpWebTarget resolveTemplate(String name, Object value) { - ImmutableList.Builder newPath = ImmutableList.builder(); + List newPath = new ArrayList<>(); for (String component : path) { component = component.replaceAll("\\{" + name + "\\}", value.toString()); newPath.add(component); } - return this.withPath(newPath.build()); + return this.withPath(newPath); } @Override From aac4affc9e8ae6f6e66ca16de00a373312a40207 Mon Sep 17 00:00:00 2001 From: Grzegorz Piwowarek Date: Sat, 2 Nov 2019 13:27:22 +0200 Subject: [PATCH 3/3] Remove redundant @NotNull annotation --- .../java/org/testcontainers/containers/GenericContainer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/org/testcontainers/containers/GenericContainer.java b/core/src/main/java/org/testcontainers/containers/GenericContainer.java index cd28d6df5dc..0888a6cd875 100644 --- a/core/src/main/java/org/testcontainers/containers/GenericContainer.java +++ b/core/src/main/java/org/testcontainers/containers/GenericContainer.java @@ -442,7 +442,6 @@ Optional findContainerForReuse(String hash) { .map(it -> it.getId()); } - @NotNull private Map labelFilterFor(String hash) { Map labels = new HashMap<>(); labels.put(HASH_LABEL, hash);