diff --git a/core/src/main/java/org/testcontainers/DockerClientFactory.java b/core/src/main/java/org/testcontainers/DockerClientFactory.java index f91b075cdb2..1905fc7c098 100644 --- a/core/src/main/java/org/testcontainers/DockerClientFactory.java +++ b/core/src/main/java/org/testcontainers/DockerClientFactory.java @@ -60,7 +60,7 @@ public class DockerClientFactory { TESTCONTAINERS_SESSION_ID_LABEL, SESSION_ID ); - private static final String TINY_IMAGE = TestcontainersConfiguration.getInstance().getTinyImage(); + private static final String TINY_IMAGE = TestcontainersConfiguration.getInstance().getTinyDockerImageName().asCanonicalNameString(); private static DockerClientFactory instance; // Cached client configuration diff --git a/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java b/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java index 50a58ba8c87..af1da29442f 100644 --- a/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java +++ b/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java @@ -586,7 +586,7 @@ class ContainerisedDockerCompose extends GenericContainer composeFiles, String identifier) { - super(TestcontainersConfiguration.getInstance().getDockerComposeContainerImage()); + super(TestcontainersConfiguration.getInstance().getDockerComposeDockerImageName()); addEnv(ENV_PROJECT_NAME, identifier); // Map the docker compose file into the container diff --git a/core/src/main/java/org/testcontainers/containers/FixedHostPortGenericContainer.java b/core/src/main/java/org/testcontainers/containers/FixedHostPortGenericContainer.java index 33c1c8e89bd..6477c28042e 100644 --- a/core/src/main/java/org/testcontainers/containers/FixedHostPortGenericContainer.java +++ b/core/src/main/java/org/testcontainers/containers/FixedHostPortGenericContainer.java @@ -12,6 +12,11 @@ * not available - which could manifest as flaky or unstable tests.

*/ public class FixedHostPortGenericContainer> extends GenericContainer { + + /** + * @deprecated it is highly recommended that {@link FixedHostPortGenericContainer} not be used, as it risks port conflicts. + */ + @Deprecated public FixedHostPortGenericContainer(@NotNull String dockerImageName) { super(dockerImageName); } diff --git a/core/src/main/java/org/testcontainers/containers/GenericContainer.java b/core/src/main/java/org/testcontainers/containers/GenericContainer.java index b3dcf469cfc..22a6c2408d6 100644 --- a/core/src/main/java/org/testcontainers/containers/GenericContainer.java +++ b/core/src/main/java/org/testcontainers/containers/GenericContainer.java @@ -12,7 +12,6 @@ import com.github.dockerjava.api.model.ContainerNetwork; import com.github.dockerjava.api.model.ExposedPort; import com.github.dockerjava.api.model.HostConfig; -import com.github.dockerjava.api.model.Info; import com.github.dockerjava.api.model.Link; import com.github.dockerjava.api.model.PortBinding; import com.github.dockerjava.api.model.Volume; @@ -55,6 +54,7 @@ import org.testcontainers.lifecycle.TestDescription; import org.testcontainers.lifecycle.TestLifecycleAware; import org.testcontainers.utility.Base58; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.DockerLoggerFactory; import org.testcontainers.utility.DockerMachineClient; import org.testcontainers.utility.MountableFile; @@ -227,10 +227,27 @@ public class GenericContainer> @Setter(AccessLevel.NONE) private boolean shouldBeReused = false; + + public GenericContainer(@NonNull final DockerImageName dockerImageName) { + this.image = new RemoteDockerImage(dockerImageName); + } + + public GenericContainer(@NonNull final RemoteDockerImage image) { + this.image = image; + } + + /** + * @deprecated use {@link GenericContainer(DockerImageName)} instead + */ + @Deprecated public GenericContainer() { this(TestcontainersConfiguration.getInstance().getTinyImage()); } + /** + * @deprecated use {@link GenericContainer(DockerImageName)} instead + */ + @Deprecated public GenericContainer(@NonNull final String dockerImageName) { this.setDockerImageName(dockerImageName); } diff --git a/core/src/main/java/org/testcontainers/containers/PortForwardingContainer.java b/core/src/main/java/org/testcontainers/containers/PortForwardingContainer.java index 09f1d98bd2d..e42f2681675 100644 --- a/core/src/main/java/org/testcontainers/containers/PortForwardingContainer.java +++ b/core/src/main/java/org/testcontainers/containers/PortForwardingContainer.java @@ -19,7 +19,7 @@ public enum PortForwardingContainer { INSTANCE; - private GenericContainer container; + private GenericContainer container; private final Set> exposedPorts = Collections.newSetFromMap(new ConcurrentHashMap<>()); @@ -29,7 +29,7 @@ public enum PortForwardingContainer { @SneakyThrows private Connection createSSHSession() { String password = UUID.randomUUID().toString(); - container = new GenericContainer<>(TestcontainersConfiguration.getInstance().getSSHdImage()) + container = new GenericContainer<>(TestcontainersConfiguration.getInstance().getSSHdDockerImageName()) .withExposedPorts(22) .withEnv("PASSWORD", password) .withCommand( diff --git a/core/src/main/java/org/testcontainers/containers/SocatContainer.java b/core/src/main/java/org/testcontainers/containers/SocatContainer.java index 5949a14490d..fbca73eb29d 100644 --- a/core/src/main/java/org/testcontainers/containers/SocatContainer.java +++ b/core/src/main/java/org/testcontainers/containers/SocatContainer.java @@ -1,6 +1,7 @@ package org.testcontainers.containers; import org.testcontainers.utility.Base58; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.TestcontainersConfiguration; import java.util.HashMap; @@ -16,7 +17,11 @@ public class SocatContainer extends GenericContainer { private final Map targets = new HashMap<>(); public SocatContainer() { - super(TestcontainersConfiguration.getInstance().getSocatContainerImage()); + this(TestcontainersConfiguration.getInstance().getSocatDockerImageName()); + } + + public SocatContainer(final DockerImageName dockerImageName) { + super(dockerImageName); withCreateContainerCmdModifier(it -> it.withEntrypoint("/bin/sh")); withCreateContainerCmdModifier(it -> it.withName("testcontainers-socat-" + Base58.randomString(8))); } @@ -39,4 +44,4 @@ protected void configure() { .collect(Collectors.joining(" & ")) ); } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/testcontainers/containers/VncRecordingContainer.java b/core/src/main/java/org/testcontainers/containers/VncRecordingContainer.java index fd48dd01f92..8ac060c2af6 100644 --- a/core/src/main/java/org/testcontainers/containers/VncRecordingContainer.java +++ b/core/src/main/java/org/testcontainers/containers/VncRecordingContainer.java @@ -52,7 +52,7 @@ public VncRecordingContainer(@NonNull GenericContainer targetContainer) { * Create a sidekick container and attach it to another container. The VNC output of that container will be recorded. */ public VncRecordingContainer(@NonNull Network network, @NonNull String targetNetworkAlias) throws IllegalStateException { - super(TestcontainersConfiguration.getInstance().getVncRecordedContainerImage()); + super(TestcontainersConfiguration.getInstance().getVncDockerImageName()); this.targetNetworkAlias = targetNetworkAlias; withNetwork(network); diff --git a/core/src/main/java/org/testcontainers/dockerclient/AuthDelegatingDockerClientConfig.java b/core/src/main/java/org/testcontainers/dockerclient/AuthDelegatingDockerClientConfig.java index c78a13c99ac..5acb7ab8835 100644 --- a/core/src/main/java/org/testcontainers/dockerclient/AuthDelegatingDockerClientConfig.java +++ b/core/src/main/java/org/testcontainers/dockerclient/AuthDelegatingDockerClientConfig.java @@ -40,7 +40,7 @@ public AuthConfig effectiveAuthConfig(String imageName) { } // try and obtain more accurate auth config using our resolution - final DockerImageName parsed = new DockerImageName(imageName); + final DockerImageName parsed = DockerImageName.parse(imageName); final AuthConfig effectiveAuthConfig = RegistryAuthLocator.instance() .lookupAuthConfig(parsed, fallbackAuthConfig); diff --git a/core/src/main/java/org/testcontainers/images/AbstractImagePullPolicy.java b/core/src/main/java/org/testcontainers/images/AbstractImagePullPolicy.java index 11c621eb08b..f5d75ad9617 100644 --- a/core/src/main/java/org/testcontainers/images/AbstractImagePullPolicy.java +++ b/core/src/main/java/org/testcontainers/images/AbstractImagePullPolicy.java @@ -12,7 +12,7 @@ public abstract class AbstractImagePullPolicy implements ImagePullPolicy { @Override public boolean shouldPull(DockerImageName imageName) { - Logger logger = DockerLoggerFactory.getLogger(imageName.toString()); + Logger logger = DockerLoggerFactory.getLogger(imageName.asCanonicalNameString()); // Does our cache already know the image? ImageData cachedImageData = LOCAL_IMAGES_CACHE.get(imageName); diff --git a/core/src/main/java/org/testcontainers/images/LocalImagesCache.java b/core/src/main/java/org/testcontainers/images/LocalImagesCache.java index e6b330d4c90..ec371ef830e 100644 --- a/core/src/main/java/org/testcontainers/images/LocalImagesCache.java +++ b/core/src/main/java/org/testcontainers/images/LocalImagesCache.java @@ -39,7 +39,7 @@ public Optional refreshCache(DockerImageName imageName) { InspectImageResponse response = null; try { - response = dockerClient.inspectImageCmd(imageName.toString()).exec(); + response = dockerClient.inspectImageCmd(imageName.asCanonicalNameString()).exec(); } catch (NotFoundException e) { log.trace("Image {} not found", imageName, e); } diff --git a/core/src/main/java/org/testcontainers/images/RemoteDockerImage.java b/core/src/main/java/org/testcontainers/images/RemoteDockerImage.java index d0e1313edf6..8d3a77c5680 100644 --- a/core/src/main/java/org/testcontainers/images/RemoteDockerImage.java +++ b/core/src/main/java/org/testcontainers/images/RemoteDockerImage.java @@ -38,12 +38,18 @@ public class RemoteDockerImage extends LazyFuture { @ToString.Exclude private DockerClient dockerClient = DockerClientFactory.lazyClient(); + public RemoteDockerImage(DockerImageName dockerImageName) { + this.imageNameFuture = CompletableFuture.completedFuture(dockerImageName); + } + + @Deprecated public RemoteDockerImage(String dockerImageName) { - this.imageNameFuture = CompletableFuture.completedFuture(new DockerImageName(dockerImageName)); + this.imageNameFuture = CompletableFuture.completedFuture(DockerImageName.parse(dockerImageName)); } + @Deprecated public RemoteDockerImage(@NonNull String repository, @NonNull String tag) { - this.imageNameFuture = CompletableFuture.completedFuture(new DockerImageName(repository, tag)); + this.imageNameFuture = CompletableFuture.completedFuture(DockerImageName.parse(repository).withTag(tag)); } public RemoteDockerImage(@NonNull Future imageFuture) { @@ -57,7 +63,7 @@ protected final String resolve() { Logger logger = DockerLoggerFactory.getLogger(imageName.toString()); try { if (!imagePullPolicy.shouldPull(imageName)) { - return imageName.toString(); + return imageName.asCanonicalNameString(); } // The image is not available locally - pull it @@ -76,7 +82,7 @@ protected final String resolve() { LocalImagesCache.INSTANCE.refreshCache(imageName); - return imageName.toString(); + return imageName.asCanonicalNameString(); } catch (InterruptedException | InternalServerErrorException e) { // these classes of exception often relate to timeout/connection errors so should be retried lastFailure = e; @@ -104,7 +110,7 @@ private String imageNameToString() { } try { - return getImageName().toString(); + return getImageName().asCanonicalNameString(); } catch (InterruptedException | ExecutionException e) { return e.getMessage(); } diff --git a/core/src/main/java/org/testcontainers/images/builder/dockerfile/traits/FromStatementTrait.java b/core/src/main/java/org/testcontainers/images/builder/dockerfile/traits/FromStatementTrait.java index 2a87cb08223..07077259df8 100644 --- a/core/src/main/java/org/testcontainers/images/builder/dockerfile/traits/FromStatementTrait.java +++ b/core/src/main/java/org/testcontainers/images/builder/dockerfile/traits/FromStatementTrait.java @@ -6,7 +6,7 @@ public interface FromStatementTrait & DockerfileBuilderTrait> { default SELF from(String dockerImageName) { - new DockerImageName(dockerImageName).assertValid(); + DockerImageName.parse(dockerImageName).assertValid(); return ((SELF) this).withStatement(new SingleArgumentStatement("FROM", dockerImageName)); } diff --git a/core/src/main/java/org/testcontainers/utility/DockerImageName.java b/core/src/main/java/org/testcontainers/utility/DockerImageName.java index d57f1044e80..b4a40be2f16 100644 --- a/core/src/main/java/org/testcontainers/utility/DockerImageName.java +++ b/core/src/main/java/org/testcontainers/utility/DockerImageName.java @@ -2,12 +2,16 @@ import com.google.common.net.HostAndPort; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; +import org.jetbrains.annotations.NotNull; import java.util.regex.Pattern; @EqualsAndHashCode(exclude = "rawName") +@AllArgsConstructor(access = AccessLevel.PRIVATE) public final class DockerImageName { /* Regex patterns used for validation */ @@ -19,22 +23,42 @@ public final class DockerImageName { private final String rawName; private final String registry; private final String repo; - private final Versioning versioning; + @NotNull private final Versioning versioning; - public DockerImageName(String name) { - this.rawName = name; - final int slashIndex = name.indexOf('/'); + /** + * Parses a docker image name from a provided string. + * + * @param fullImageName in standard Docker format, e.g. name:tag, + * some.registry/path/name:tag, + * some.registry/path/name@sha256:abcdef..., etc. + */ + public static DockerImageName parse(String fullImageName) { + return new DockerImageName(fullImageName); + } + + /** + * Parses a docker image name from a provided string. + * + * @param fullImageName in standard Docker format, e.g. name:tag, + * some.registry/path/name:tag, + * some.registry/path/name@sha256:abcdef..., etc. + * @deprecated use {@link DockerImageName#parse(String)} instead + */ + @Deprecated + public DockerImageName(String fullImageName) { + this.rawName = fullImageName; + final int slashIndex = fullImageName.indexOf('/'); String remoteName; if (slashIndex == -1 || - (!name.substring(0, slashIndex).contains(".") && - !name.substring(0, slashIndex).contains(":") && - !name.substring(0, slashIndex).equals("localhost"))) { + (!fullImageName.substring(0, slashIndex).contains(".") && + !fullImageName.substring(0, slashIndex).contains(":") && + !fullImageName.substring(0, slashIndex).equals("localhost"))) { registry = ""; - remoteName = name; + remoteName = fullImageName; } else { - registry = name.substring(0, slashIndex); - remoteName = name.substring(slashIndex + 1); + registry = fullImageName.substring(0, slashIndex); + remoteName = fullImageName.substring(slashIndex + 1); } if (remoteName.contains("@sha256:")) { @@ -49,28 +73,40 @@ public DockerImageName(String name) { } } - public DockerImageName(String name, String tag) { - this.rawName = name; - final int slashIndex = name.indexOf('/'); + /** + * Parses a docker image name from a provided string, and uses a separate provided version. + * + * @param nameWithoutTag in standard Docker format, e.g. name, + * some.registry/path/name, + * some.registry/path/name, etc. + * @param version a docker image version identifier, either as a tag or sha256 checksum, e.g. + * tag, + * sha256:abcdef.... + * @deprecated use {@link DockerImageName#parse(String)}.{@link DockerImageName#withTag(String)} instead + */ + @Deprecated + public DockerImageName(String nameWithoutTag, @NotNull String version) { + this.rawName = nameWithoutTag; + final int slashIndex = nameWithoutTag.indexOf('/'); String remoteName; if (slashIndex == -1 || - (!name.substring(0, slashIndex).contains(".") && - !name.substring(0, slashIndex).contains(":") && - !name.substring(0, slashIndex).equals("localhost"))) { + (!nameWithoutTag.substring(0, slashIndex).contains(".") && + !nameWithoutTag.substring(0, slashIndex).contains(":") && + !nameWithoutTag.substring(0, slashIndex).equals("localhost"))) { registry = ""; - remoteName = name; + remoteName = nameWithoutTag; } else { - registry = name.substring(0, slashIndex); - remoteName = name.substring(slashIndex + 1); + registry = nameWithoutTag.substring(0, slashIndex); + remoteName = nameWithoutTag.substring(slashIndex + 1); } - if (tag.startsWith("sha256:")) { + if (version.startsWith("sha256:")) { repo = remoteName; - versioning = new Sha256Versioning(tag.replace("sha256:", "")); + versioning = new Sha256Versioning(version.replace("sha256:", "")); } else { repo = remoteName; - versioning = new TagVersioning(tag); + versioning = new TagVersioning(version); } } @@ -92,13 +128,16 @@ public String getVersionPart() { return versioning.toString(); } + /** + * @return canonical name for the image + */ + public String asCanonicalNameString() { + return getUnversionedPart() + versioning.getSeparator() + versioning.toString(); + } + @Override public String toString() { - if (versioning == null) { - return getUnversionedPart(); - } else { - return getUnversionedPart() + versioning.getSeparator() + versioning.toString(); - } + return asCanonicalNameString(); } /** @@ -111,10 +150,6 @@ public void assertValid() { if (!REPO_NAME.matcher(repo).matches()) { throw new IllegalArgumentException(repo + " is not a valid Docker image name (in " + rawName + ")"); } - if (versioning == null) { - throw new IllegalArgumentException("No image tag was specified in docker image name " + - "(" + rawName + "). Please provide a tag; this may be 'latest' or a specific version"); - } if (!versioning.isValid()) { throw new IllegalArgumentException(versioning + " is not a valid image versioning identifier (in " + rawName + ")"); } @@ -124,8 +159,13 @@ public String getRegistry() { return registry; } + public DockerImageName withTag(final String newTag) { + return new DockerImageName(rawName, registry, repo, new TagVersioning(newTag)); + } + private interface Versioning { boolean isValid(); + String getSeparator(); } @@ -155,7 +195,7 @@ public String toString() { } @Data - private class Sha256Versioning implements Versioning { + private static class Sha256Versioning implements Versioning { public static final String HASH_REGEX = "[0-9a-fA-F]{32,}"; private final String hash; diff --git a/core/src/main/java/org/testcontainers/utility/DockerMachineClient.java b/core/src/main/java/org/testcontainers/utility/DockerMachineClient.java index 240a6d5afb4..fe12e9f541d 100644 --- a/core/src/main/java/org/testcontainers/utility/DockerMachineClient.java +++ b/core/src/main/java/org/testcontainers/utility/DockerMachineClient.java @@ -1,7 +1,6 @@ package org.testcontainers.utility; import lombok.NonNull; - import org.apache.commons.lang.SystemUtils; import org.slf4j.Logger; diff --git a/core/src/main/java/org/testcontainers/utility/ResourceReaper.java b/core/src/main/java/org/testcontainers/utility/ResourceReaper.java index 0a0728e9306..3448e73dce3 100644 --- a/core/src/main/java/org/testcontainers/utility/ResourceReaper.java +++ b/core/src/main/java/org/testcontainers/utility/ResourceReaper.java @@ -14,7 +14,6 @@ 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; import org.rnorth.ducttape.ratelimits.RateLimiter; @@ -22,6 +21,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testcontainers.DockerClientFactory; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -72,7 +72,7 @@ private ResourceReaper() { @SneakyThrows(InterruptedException.class) public static String start(String hostIpAddress, DockerClient client) { - String ryukImage = TestcontainersConfiguration.getInstance().getRyukImage(); + String ryukImage = TestcontainersConfiguration.getInstance().getRyukDockerImageName().asCanonicalNameString(); DockerClientFactory.instance().checkAndPullImage(client, ryukImage); List binds = new ArrayList<>(); diff --git a/core/src/main/java/org/testcontainers/utility/TestcontainersConfiguration.java b/core/src/main/java/org/testcontainers/utility/TestcontainersConfiguration.java index aa829573447..1939e8e21b3 100644 --- a/core/src/main/java/org/testcontainers/utility/TestcontainersConfiguration.java +++ b/core/src/main/java/org/testcontainers/utility/TestcontainersConfiguration.java @@ -63,50 +63,95 @@ public String getAmbassadorContainerImage() { return (String) properties.getOrDefault("ambassador.container.image", "richnorth/ambassador:latest"); } + @Deprecated public String getSocatContainerImage() { return (String) properties.getOrDefault("socat.container.image", "alpine/socat:latest"); } + public DockerImageName getSocatDockerImageName() { + return DockerImageName.parse(getSocatContainerImage()); + } + + @Deprecated public String getVncRecordedContainerImage() { return (String) properties.getOrDefault("vncrecorder.container.image", "testcontainers/vnc-recorder:1.1.0"); } + public DockerImageName getVncDockerImageName() { + return DockerImageName.parse(getVncRecordedContainerImage()); + } + + @Deprecated public String getDockerComposeContainerImage() { return (String) properties.getOrDefault("compose.container.image", "docker/compose:1.24.1"); } + public DockerImageName getDockerComposeDockerImageName() { + return DockerImageName.parse(getDockerComposeContainerImage()); + } + + @Deprecated public String getTinyImage() { return (String) properties.getOrDefault("tinyimage.container.image", "alpine:3.5"); } + public DockerImageName getTinyDockerImageName() { + return DockerImageName.parse(getTinyImage()); + } + public boolean isRyukPrivileged() { return Boolean.parseBoolean((String) properties.getOrDefault("ryuk.container.privileged", "false")); } + @Deprecated public String getRyukImage() { return (String) properties.getOrDefault("ryuk.container.image", "testcontainers/ryuk:0.3.0"); } + public DockerImageName getRyukDockerImageName() { + return DockerImageName.parse(getRyukImage()); + } + + @Deprecated public String getSSHdImage() { return (String) properties.getOrDefault("sshd.container.image", "testcontainers/sshd:1.0.0"); } + public DockerImageName getSSHdDockerImageName() { + return DockerImageName.parse(getSSHdImage()); + } + public Integer getRyukTimeout() { return Integer.parseInt((String) properties.getOrDefault("ryuk.container.timeout", "30")); } + @Deprecated public String getKafkaImage() { return (String) properties.getOrDefault("kafka.container.image", "confluentinc/cp-kafka"); } + public DockerImageName getKafkaDockerImageName() { + return DockerImageName.parse(getKafkaImage()); + } + + @Deprecated public String getPulsarImage() { return (String) properties.getOrDefault("pulsar.container.image", "apachepulsar/pulsar"); } + public DockerImageName getPulsarDockerImageName() { + return DockerImageName.parse(getPulsarImage()); + } + + @Deprecated public String getLocalStackImage() { return (String) properties.getOrDefault("localstack.container.image", "localstack/localstack"); } + public DockerImageName getLocalstackDockerImageName() { + return DockerImageName.parse(getLocalStackImage()); + } + public boolean isDisableChecks() { return Boolean.parseBoolean((String) environmentProperties.getOrDefault("checks.disable", "false")); } diff --git a/core/src/test/java/alt/testcontainers/images/OutOfPackageImagePullPolicyTest.java b/core/src/test/java/alt/testcontainers/images/OutOfPackageImagePullPolicyTest.java index 2da41a8344e..e4197c7c1f6 100644 --- a/core/src/test/java/alt/testcontainers/images/OutOfPackageImagePullPolicyTest.java +++ b/core/src/test/java/alt/testcontainers/images/OutOfPackageImagePullPolicyTest.java @@ -7,11 +7,13 @@ import org.testcontainers.images.ImageData; import org.testcontainers.utility.DockerImageName; +import static org.testcontainers.TestImages.TINY_IMAGE; + public class OutOfPackageImagePullPolicyTest { @Test public void shouldSupportCustomPoliciesOutOfTestContainersPackage() { try ( - GenericContainer container = new GenericContainer<>() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withImagePullPolicy(new AbstractImagePullPolicy() { @Override protected boolean shouldPullCached(DockerImageName imageName, ImageData localImageData) { diff --git a/core/src/test/java/org/testcontainers/DaemonTest.java b/core/src/test/java/org/testcontainers/DaemonTest.java index e339f30acc9..f08614c8cdc 100644 --- a/core/src/test/java/org/testcontainers/DaemonTest.java +++ b/core/src/test/java/org/testcontainers/DaemonTest.java @@ -10,6 +10,7 @@ import java.util.stream.Collectors; import static org.junit.Assert.assertEquals; +import static org.testcontainers.TestImages.TINY_IMAGE; /** * This test forks a new JVM, otherwise it's not possible to reliably diff the threads @@ -19,10 +20,10 @@ public class DaemonTest { public static void main(String[] args) { Thread mainThread = Thread.currentThread(); - GenericContainer genericContainer = null; + GenericContainer genericContainer = null; try { - genericContainer = new GenericContainer().withCommand("top"); + genericContainer = new GenericContainer<>(TINY_IMAGE).withCommand("top"); genericContainer.start(); Set threads = new HashSet<>(Thread.getAllStackTraces().keySet()); diff --git a/core/src/test/java/org/testcontainers/DockerClientFactoryTest.java b/core/src/test/java/org/testcontainers/DockerClientFactoryTest.java index 04edd407959..030e4164f00 100644 --- a/core/src/test/java/org/testcontainers/DockerClientFactoryTest.java +++ b/core/src/test/java/org/testcontainers/DockerClientFactoryTest.java @@ -30,7 +30,7 @@ public void runCommandInsideDockerShouldNotFailIfImageDoesNotExistsLocally() { try { //remove tiny image, so it will be pulled during next command run dockFactory.client() - .removeImageCmd(TestcontainersConfiguration.getInstance().getTinyImage()) + .removeImageCmd(TestcontainersConfiguration.getInstance().getTinyDockerImageName().asCanonicalNameString()) .withForce(true).exec(); } catch (NotFoundException ignored) { // Do not fail if it's not pulled yet diff --git a/core/src/test/java/org/testcontainers/TestImages.java b/core/src/test/java/org/testcontainers/TestImages.java new file mode 100644 index 00000000000..3f16e88d882 --- /dev/null +++ b/core/src/test/java/org/testcontainers/TestImages.java @@ -0,0 +1,13 @@ +package org.testcontainers; + +import org.testcontainers.utility.DockerImageName; +import org.testcontainers.utility.TestcontainersConfiguration; + +public interface TestImages { + DockerImageName REDIS_IMAGE = DockerImageName.parse("redis:3.0.2"); + DockerImageName RABBITMQ_IMAGE = DockerImageName.parse("rabbitmq:3.5.3"); + DockerImageName MONGODB_IMAGE = DockerImageName.parse("mongo:3.1.5"); + DockerImageName ALPINE_IMAGE = DockerImageName.parse("alpine:3.2"); + DockerImageName DOCKER_REGISTRY_IMAGE = DockerImageName.parse("registry:2.7.0"); + DockerImageName TINY_IMAGE = TestcontainersConfiguration.getInstance().getTinyDockerImageName(); +} diff --git a/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java b/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java index 8c98b0730b0..d17b0709dfa 100644 --- a/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java +++ b/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java @@ -12,6 +12,7 @@ import java.net.InetSocketAddress; import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.testcontainers.TestImages.TINY_IMAGE; public class ExposedHostTest { @@ -31,9 +32,9 @@ public static void setUpClass() throws Exception { server.start(); Testcontainers.exposeHostPorts(server.getAddress().getPort()); - + Testcontainers.exposeHostPorts(ImmutableMap.of(server.getAddress().getPort(), 80)); - Testcontainers.exposeHostPorts(ImmutableMap.of(server.getAddress().getPort(), 81)); + Testcontainers.exposeHostPorts(ImmutableMap.of(server.getAddress().getPort(), 81)); } @AfterClass @@ -43,24 +44,33 @@ public static void tearDownClass() throws Exception { @Test public void testExposedHost() throws Exception { - assertResponse(new GenericContainer().withCommand("top"), server.getAddress().getPort()); + assertResponse(new GenericContainer<>(TINY_IMAGE) + .withCommand("top"), + server.getAddress().getPort()); } @Test public void testExposedHostWithNetwork() throws Exception { try (Network network = Network.newNetwork()) { - assertResponse(new GenericContainer().withNetwork(network).withCommand("top"), server.getAddress().getPort()); + assertResponse(new GenericContainer<>(TINY_IMAGE) + .withNetwork(network) + .withCommand("top"), + server.getAddress().getPort()); } } - + @Test public void testExposedHostPortOnFixedInternalPorts() throws Exception { - assertResponse(new GenericContainer().withCommand("top"), 80); - assertResponse(new GenericContainer().withCommand("top"), 81); - } + assertResponse(new GenericContainer<>(TINY_IMAGE) + .withCommand("top"), + 80); + assertResponse(new GenericContainer<>(TINY_IMAGE) + .withCommand("top"), + 81); + } @SneakyThrows - protected void assertResponse(GenericContainer container, int port) { + protected void assertResponse(GenericContainer container, int port) { try { container.start(); diff --git a/core/src/test/java/org/testcontainers/containers/FailureDetectingExternalResourceTest.java b/core/src/test/java/org/testcontainers/containers/FailureDetectingExternalResourceTest.java index 15a9eba7d17..63993bc24ff 100644 --- a/core/src/test/java/org/testcontainers/containers/FailureDetectingExternalResourceTest.java +++ b/core/src/test/java/org/testcontainers/containers/FailureDetectingExternalResourceTest.java @@ -3,6 +3,7 @@ import org.junit.Test; import org.junit.runner.Description; import org.junit.runners.model.Statement; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; diff --git a/core/src/test/java/org/testcontainers/containers/GenericContainerTest.java b/core/src/test/java/org/testcontainers/containers/GenericContainerTest.java index 134bdf18f30..5008ba5baca 100644 --- a/core/src/test/java/org/testcontainers/containers/GenericContainerTest.java +++ b/core/src/test/java/org/testcontainers/containers/GenericContainerTest.java @@ -11,6 +11,7 @@ import org.assertj.core.api.Assumptions; import org.junit.Test; import org.rnorth.ducttape.unreliables.Unreliables; +import org.testcontainers.TestImages; import org.testcontainers.DockerClientFactory; import org.testcontainers.containers.startupcheck.StartupCheckStrategy; import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy; @@ -28,7 +29,7 @@ public void shouldReportOOMAfterWait() { // Poor man's rootless Docker detection :D Assumptions.assumeThat(info.getDriver()).doesNotContain("vfs"); try ( - GenericContainer container = new GenericContainer<>() + GenericContainer container = new GenericContainer<>(TestImages.TINY_IMAGE) .withStartupCheckStrategy(new NoopStartupCheckStrategy()) .waitingFor(new WaitForExitedState(ContainerState::getOOMKilled)) .withCreateContainerCmdModifier(it -> { @@ -49,7 +50,7 @@ public void shouldReportOOMAfterWait() { @Test public void shouldReportErrorAfterWait() { try ( - GenericContainer container = new GenericContainer<>() + GenericContainer container = new GenericContainer<>(TestImages.TINY_IMAGE) .withStartupCheckStrategy(new NoopStartupCheckStrategy()) .waitingFor(new WaitForExitedState(state -> state.getExitCode() > 0)) .withCommand("sh", "-c", "usleep 100; exit 123") diff --git a/core/src/test/java/org/testcontainers/containers/NetworkTest.java b/core/src/test/java/org/testcontainers/containers/NetworkTest.java index b717b8dc81a..a39f0552a5a 100644 --- a/core/src/test/java/org/testcontainers/containers/NetworkTest.java +++ b/core/src/test/java/org/testcontainers/containers/NetworkTest.java @@ -5,9 +5,11 @@ import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; import org.testcontainers.DockerClientFactory; -import org.testcontainers.containers.Network; +import org.testcontainers.TestImages; -import static org.rnorth.visibleassertions.VisibleAssertions.*; +import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.rnorth.visibleassertions.VisibleAssertions.assertNotEquals; +import static org.rnorth.visibleassertions.VisibleAssertions.assertNotNull; import static org.testcontainers.containers.Network.newNetwork; @RunWith(Enclosed.class) @@ -19,13 +21,13 @@ public static class WithRules { public Network network = newNetwork(); @Rule - public GenericContainer foo = new GenericContainer() + public GenericContainer foo = new GenericContainer<>(TestImages.TINY_IMAGE) .withNetwork(network) .withNetworkAliases("foo") .withCommand("/bin/sh", "-c", "while true ; do printf 'HTTP/1.1 200 OK\\n\\nyay' | nc -l -p 8080; done"); @Rule - public GenericContainer bar = new GenericContainer() + public GenericContainer bar = new GenericContainer<>(TestImages.TINY_IMAGE) .withNetwork(network) .withCommand("top"); @@ -44,12 +46,12 @@ public void testNetworkSupport() throws Exception { try ( Network network = Network.newNetwork(); - GenericContainer foo = new GenericContainer() + GenericContainer foo = new GenericContainer<>(TestImages.TINY_IMAGE) .withNetwork(network) .withNetworkAliases("foo") .withCommand("/bin/sh", "-c", "while true ; do printf 'HTTP/1.1 200 OK\\n\\nyay' | nc -l -p 8080; done"); - GenericContainer bar = new GenericContainer() + GenericContainer bar = new GenericContainer<>(TestImages.TINY_IMAGE) .withNetwork(network) .withCommand("top") ) { @@ -63,11 +65,11 @@ public void testNetworkSupport() throws Exception { } @Test - public void testBuilder() throws Exception { + public void testBuilder() { try ( Network network = Network.builder() .driver("macvlan") - .build(); + .build() ) { String id = network.getId(); assertEquals( @@ -79,11 +81,11 @@ public void testBuilder() throws Exception { } @Test - public void testModifiers() throws Exception { + public void testModifiers() { try ( Network network = Network.builder() .createNetworkCmdModifier(cmd -> cmd.withDriver("macvlan")) - .build(); + .build() ) { String id = network.getId(); assertEquals( @@ -95,7 +97,7 @@ public void testModifiers() throws Exception { } @Test - public void testReusability() throws Exception { + public void testReusability() { try (Network network = Network.newNetwork()) { String firstId = network.getId(); assertNotNull( diff --git a/core/src/test/java/org/testcontainers/containers/ReusabilityUnitTests.java b/core/src/test/java/org/testcontainers/containers/ReusabilityUnitTests.java index b2d4d327ba2..c212d04c33a 100644 --- a/core/src/test/java/org/testcontainers/containers/ReusabilityUnitTests.java +++ b/core/src/test/java/org/testcontainers/containers/ReusabilityUnitTests.java @@ -3,7 +3,12 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.dockerjava.api.DockerClient; -import com.github.dockerjava.api.command.*; +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerCmd; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.command.ListContainersCmd; +import com.github.dockerjava.api.command.StartContainerCmd; import com.github.dockerjava.api.model.Container; import com.github.dockerjava.core.command.CreateContainerCmdImpl; import com.github.dockerjava.core.command.InspectContainerCmdImpl; @@ -35,7 +40,6 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -45,14 +49,11 @@ import static org.assertj.core.api.Assumptions.assumeThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; +import static org.testcontainers.TestImages.TINY_IMAGE; @RunWith(Enclosed.class) public class ReusabilityUnitTests { - static final CompletableFuture IMAGE_FUTURE = CompletableFuture.completedFuture( - TestcontainersConfiguration.getInstance().getTinyImage() - ); - @RunWith(Parameterized.class) @RequiredArgsConstructor @FieldDefaults(makeFinal = true) @@ -61,8 +62,8 @@ public static class CanBeReusedTest { @Parameterized.Parameters(name = "{0}") public static Object[][] data() { return new Object[][] { - { "generic", new GenericContainer(IMAGE_FUTURE), true }, - { "anonymous generic", new GenericContainer(IMAGE_FUTURE) {}, true }, + { "generic", new GenericContainer<>(TINY_IMAGE), true }, + { "anonymous generic", new GenericContainer(TINY_IMAGE) {}, true }, { "custom", new CustomContainer(), true }, { "anonymous custom", new CustomContainer() {}, true }, { "custom with containerIsCreated", new CustomContainerWithContainerIsCreated(), false }, @@ -84,16 +85,16 @@ public void shouldBeReusable() { } } - static class CustomContainer extends GenericContainer { + static class CustomContainer extends GenericContainer { CustomContainer() { - super(IMAGE_FUTURE); + super(TINY_IMAGE); } } - static class CustomContainerWithContainerIsCreated extends GenericContainer { + static class CustomContainerWithContainerIsCreated extends GenericContainer { CustomContainerWithContainerIsCreated() { - super(IMAGE_FUTURE); + super(TINY_IMAGE); } @Override @@ -109,7 +110,7 @@ public static class HooksTest extends AbstractReusabilityTest { List script = new ArrayList<>(); - GenericContainer container = makeReusable(new GenericContainer(IMAGE_FUTURE) { + GenericContainer container = makeReusable(new GenericContainer(TINY_IMAGE) { @Override protected boolean canBeReused() { @@ -188,7 +189,7 @@ public void shouldNotCallHookIfNotReused() { @FieldDefaults(makeFinal = true) public static class HashTest extends AbstractReusabilityTest { - protected GenericContainer container = makeReusable(new GenericContainer(IMAGE_FUTURE) { + protected GenericContainer container = makeReusable(new GenericContainer(TINY_IMAGE) { @Override public void copyFileToContainer(MountableFile mountableFile, String containerPath) { // NOOP @@ -296,7 +297,7 @@ public void shouldHashCopiedFiles() { @RunWith(BlockJUnit4ClassRunner.class) @FieldDefaults(makeFinal = true) public static class CopyFilesHashTest { - GenericContainer container = new GenericContainer(IMAGE_FUTURE); + GenericContainer container = new GenericContainer<>(TINY_IMAGE); @Test public void empty() { diff --git a/core/src/test/java/org/testcontainers/containers/output/ContainerLogsTest.java b/core/src/test/java/org/testcontainers/containers/output/ContainerLogsTest.java index ad0e4c76ae2..05ef7373293 100644 --- a/core/src/test/java/org/testcontainers/containers/output/ContainerLogsTest.java +++ b/core/src/test/java/org/testcontainers/containers/output/ContainerLogsTest.java @@ -7,6 +7,7 @@ import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.testcontainers.TestImages.ALPINE_IMAGE; import static org.testcontainers.containers.output.OutputFrame.OutputType.STDERR; import static org.testcontainers.containers.output.OutputFrame.OutputType.STDOUT; @@ -15,7 +16,7 @@ public class ContainerLogsTest { @Test @Ignore("fails due to the timing of the shell's decision to flush") public void getLogsReturnsAllLogsToDate() { - try (GenericContainer container = shortLivedContainer()) { + try (GenericContainer container = shortLivedContainer()) { container.start(); final String logs = container.getLogs(); @@ -25,7 +26,7 @@ public void getLogsReturnsAllLogsToDate() { @Test public void getLogsContainsBothOutputTypes() { - try (GenericContainer container = shortLivedContainer()) { + try (GenericContainer container = shortLivedContainer()) { container.start(); // docsGetAllLogs { @@ -38,7 +39,7 @@ public void getLogsContainsBothOutputTypes() { @Test public void getLogsReturnsStdOutToDate() { - try (GenericContainer container = shortLivedContainer()) { + try (GenericContainer container = shortLivedContainer()) { container.start(); // docsGetStdOut { @@ -50,7 +51,7 @@ public void getLogsReturnsStdOutToDate() { @Test public void getLogsReturnsStdErrToDate() { - try (GenericContainer container = shortLivedContainer()) { + try (GenericContainer container = shortLivedContainer()) { container.start(); // docsGetStdErr { @@ -62,7 +63,7 @@ public void getLogsReturnsStdErrToDate() { @Test public void getLogsForLongRunningContainer() throws InterruptedException { - try (GenericContainer container = longRunningContainer()) { + try (GenericContainer container = longRunningContainer()) { container.start(); Thread.sleep(1000L); @@ -72,14 +73,14 @@ public void getLogsForLongRunningContainer() throws InterruptedException { } } - private static GenericContainer shortLivedContainer() { - return new GenericContainer("alpine:3.3") + private static GenericContainer shortLivedContainer() { + return new GenericContainer<>(ALPINE_IMAGE) .withCommand("/bin/sh", "-c", "echo -n 'stdout' && echo -n 'stderr' 1>&2") .withStartupCheckStrategy(new OneShotStartupCheckStrategy()); } - private static GenericContainer longRunningContainer() { - return new GenericContainer("alpine:3.3") + private static GenericContainer longRunningContainer() { + return new GenericContainer<>(ALPINE_IMAGE) .withCommand("ping -c 100 127.0.0.1"); } } diff --git a/core/src/test/java/org/testcontainers/dockerclient/EventStreamTest.java b/core/src/test/java/org/testcontainers/dockerclient/EventStreamTest.java index 4d7a4e21133..a43a001ca5b 100644 --- a/core/src/test/java/org/testcontainers/dockerclient/EventStreamTest.java +++ b/core/src/test/java/org/testcontainers/dockerclient/EventStreamTest.java @@ -16,6 +16,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.testcontainers.TestImages.TINY_IMAGE; + /** * Test that event streaming from the {@link DockerClient} works correctly */ @@ -32,7 +34,7 @@ public void test() throws IOException, InterruptedException { CountDownLatch latch = new CountDownLatch(1); try ( - GenericContainer container = new GenericContainer<>() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withCommand("true") .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) ) { diff --git a/core/src/test/java/org/testcontainers/dockerclient/ImagePullTest.java b/core/src/test/java/org/testcontainers/dockerclient/ImagePullTest.java index 6e319838888..fd936d26c19 100644 --- a/core/src/test/java/org/testcontainers/dockerclient/ImagePullTest.java +++ b/core/src/test/java/org/testcontainers/dockerclient/ImagePullTest.java @@ -5,11 +5,12 @@ import org.junit.runners.Parameterized; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy; +import org.testcontainers.utility.DockerImageName; @RunWith(Parameterized.class) public class ImagePullTest { - private String image; + private final String image; @Parameterized.Parameters(name = "{0}") public static String[] parameters() { @@ -34,7 +35,7 @@ public ImagePullTest(String image) { @Test public void test() { - try (final GenericContainer container = new GenericContainer<>(image) + try (final GenericContainer container = new GenericContainer<>(DockerImageName.parse(image)) .withCommand("/bin/sh", "-c", "sleep 0") .withStartupCheckStrategy(new OneShotStartupCheckStrategy())) { container.start(); diff --git a/core/src/test/java/org/testcontainers/images/AgeBasedPullPolicyTest.java b/core/src/test/java/org/testcontainers/images/AgeBasedPullPolicyTest.java index 20b52798d40..e073fa0522a 100644 --- a/core/src/test/java/org/testcontainers/images/AgeBasedPullPolicyTest.java +++ b/core/src/test/java/org/testcontainers/images/AgeBasedPullPolicyTest.java @@ -13,7 +13,7 @@ public class AgeBasedPullPolicyTest { - final DockerImageName imageName = new DockerImageName(UUID.randomUUID().toString()); + final DockerImageName imageName = DockerImageName.parse(UUID.randomUUID().toString()); @Test public void shouldPull() { diff --git a/core/src/test/java/org/testcontainers/images/ImagePullPolicyTest.java b/core/src/test/java/org/testcontainers/images/ImagePullPolicyTest.java index 69e68f7f225..9b22f5e6166 100644 --- a/core/src/test/java/org/testcontainers/images/ImagePullPolicyTest.java +++ b/core/src/test/java/org/testcontainers/images/ImagePullPolicyTest.java @@ -1,12 +1,9 @@ package org.testcontainers.images; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; - import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.async.ResultCallback; +import com.github.dockerjava.api.command.PullImageResultCallback; import com.github.dockerjava.api.exception.NotFoundException; -import com.github.dockerjava.core.command.PullImageResultCallback; -import com.github.dockerjava.core.command.PushImageResultCallback; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -23,20 +20,24 @@ import java.util.UUID; import java.util.concurrent.TimeUnit; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.testcontainers.TestImages.DOCKER_REGISTRY_IMAGE; + public class ImagePullPolicyTest { @ClassRule - public static GenericContainer registry = new GenericContainer<>("registry:2") + public static GenericContainer registry = new GenericContainer<>(DOCKER_REGISTRY_IMAGE) .withExposedPorts(5000); - private static String imageName; + private static DockerImageName imageName; @BeforeClass public static void beforeClass() throws Exception { String testRegistryAddress = registry.getHost() + ":" + registry.getFirstMappedPort(); String testImageName = testRegistryAddress + "/image-pull-policy-test"; String tag = UUID.randomUUID().toString(); - imageName = testImageName + ":" + tag; + imageName = DockerImageName.parse(testImageName).withTag(tag); DockerClient client = DockerClientFactory.instance().client(); String dummySourceImage = "hello-world:latest"; @@ -47,28 +48,22 @@ public static void beforeClass() throws Exception { // push the image to the registry client.tagImageCmd(dummyImageId, testImageName, tag).exec(); - client.pushImageCmd(imageName) - .exec(new PushImageResultCallback()) + client.pushImageCmd(imageName.asCanonicalNameString()) + .exec(new ResultCallback.Adapter<>()) .awaitCompletion(1, TimeUnit.MINUTES); } @AfterClass public static void afterClass() { - try { - DockerClientFactory.instance().client().removeImageCmd(imageName).withForce(true).exec(); - } catch (NotFoundException ignored) { - } + removeImage(); } @Before public void setUp() { // Clean up local cache - try { - DockerClientFactory.instance().client().removeImageCmd(imageName).withForce(true).exec(); - } catch (NotFoundException ignored) { - } + removeImage(); - LocalImagesCache.INSTANCE.cache.remove(new DockerImageName(imageName)); + LocalImagesCache.INSTANCE.cache.remove(imageName); } @Test @@ -90,7 +85,7 @@ public void shouldAlwaysPull() { container.start(); } - DockerClientFactory.instance().client().removeImageCmd(imageName).withForce(true).exec(); + removeImage(); try ( GenericContainer container = new GenericContainer<>(imageName) @@ -175,4 +170,13 @@ private void expectToFailWithNotFoundException(GenericContainer container) { } } + private static void removeImage() { + try { + DockerClientFactory.instance().client() + .removeImageCmd(imageName.asCanonicalNameString()) + .withForce(true) + .exec(); + } catch (NotFoundException ignored) { + } + } } diff --git a/core/src/test/java/org/testcontainers/images/RemoteDockerImageTest.java b/core/src/test/java/org/testcontainers/images/RemoteDockerImageTest.java index 6b6a82559bf..d2ea3e7188a 100644 --- a/core/src/test/java/org/testcontainers/images/RemoteDockerImageTest.java +++ b/core/src/test/java/org/testcontainers/images/RemoteDockerImageTest.java @@ -1,23 +1,24 @@ package org.testcontainers.images; -import static org.hamcrest.CoreMatchers.containsString; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; - import org.junit.Test; import org.testcontainers.utility.Base58; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.LazyFuture; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; + public class RemoteDockerImageTest { @Test public void toStringContainsOnlyImageName() { String imageName = Base58.randomString(8).toLowerCase(); - RemoteDockerImage remoteDockerImage = new RemoteDockerImage(imageName); + RemoteDockerImage remoteDockerImage = new RemoteDockerImage(DockerImageName.parse(imageName)); assertThat(remoteDockerImage.toString(), containsString("imageName=" + imageName)); } diff --git a/core/src/test/java/org/testcontainers/images/builder/DockerignoreTest.java b/core/src/test/java/org/testcontainers/images/builder/DockerignoreTest.java index faf5fb950b8..b99a70a7650 100644 --- a/core/src/test/java/org/testcontainers/images/builder/DockerignoreTest.java +++ b/core/src/test/java/org/testcontainers/images/builder/DockerignoreTest.java @@ -1,21 +1,21 @@ package org.testcontainers.images.builder; -import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; -import static org.rnorth.visibleassertions.VisibleAssertions.fail; - -import java.nio.file.Path; -import java.nio.file.Paths; - +import com.github.dockerjava.api.exception.DockerClientException; import org.junit.Test; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy; +import org.testcontainers.utility.DockerImageName; -import com.github.dockerjava.api.exception.DockerClientException; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.rnorth.visibleassertions.VisibleAssertions.fail; public class DockerignoreTest { - + private static final Path INVALID_DOCKERIGNORE_PATH = Paths.get("src/test/resources/dockerfile-build-invalid"); - + @Test public void testInvalidDockerignore() throws Exception { try { @@ -24,13 +24,13 @@ public void testInvalidDockerignore() throws Exception { .withDockerfile(INVALID_DOCKERIGNORE_PATH.resolve("Dockerfile")) .get(); fail("Should not be able to build an image with an invalid .dockerignore file"); - } + } catch (DockerClientException e) { if (!e.getMessage().contains("Invalid pattern")) throw e; } } - + @SuppressWarnings("resource") @Test public void testValidDockerignore() throws Exception { @@ -38,7 +38,7 @@ public void testValidDockerignore() throws Exception { .withFileFromPath(".", DockerfileBuildTest.RESOURCE_PATH) .withDockerfile(DockerfileBuildTest.RESOURCE_PATH.resolve("Dockerfile-currentdir")); try( - final GenericContainer container = new GenericContainer<>(img.get()) + final GenericContainer container = new GenericContainer(DockerImageName.parse(img.get())) .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) .withCommand("ls", "/") ) { @@ -46,11 +46,11 @@ public void testValidDockerignore() throws Exception { container.start(); final String logs = container.getLogs(); - assertTrue("Files in the container indicated the .dockerignore was not applied. Output was: " + logs, + assertTrue("Files in the container indicated the .dockerignore was not applied. Output was: " + logs, logs.contains("should_not_be_ignored.txt")); - assertTrue("Files in the container indicated the .dockerignore was not applied. Output was: " + logs, + assertTrue("Files in the container indicated the .dockerignore was not applied. Output was: " + logs, !logs.contains("should_be_ignored.txt")); } } - + } diff --git a/core/src/test/java/org/testcontainers/junit/CopyFileToContainerTest.java b/core/src/test/java/org/testcontainers/junit/CopyFileToContainerTest.java index ed6ee561505..b0ed90d9c9e 100644 --- a/core/src/test/java/org/testcontainers/junit/CopyFileToContainerTest.java +++ b/core/src/test/java/org/testcontainers/junit/CopyFileToContainerTest.java @@ -11,6 +11,7 @@ import static org.rnorth.visibleassertions.VisibleAssertions.assertFalse; import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.testcontainers.TestImages.TINY_IMAGE; public class CopyFileToContainerTest { private static String containerPath = "/tmp/mappable-resource/"; @@ -19,7 +20,7 @@ public class CopyFileToContainerTest { @Test public void checkFileCopied() throws IOException, InterruptedException { try ( - GenericContainer container = new GenericContainer() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withCommand("sleep", "3000") .withCopyFileToContainer(MountableFile.forClasspathResource("/mappable-resource/"), containerPath) ) { @@ -32,7 +33,7 @@ public void checkFileCopied() throws IOException, InterruptedException { @Test public void shouldUseCopyForReadOnlyClasspathResources() throws Exception { try ( - GenericContainer container = new GenericContainer() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withCommand("sleep", "3000") .withClasspathResourceMapping("/mappable-resource/", containerPath, BindMode.READ_ONLY) ) { @@ -45,7 +46,7 @@ public void shouldUseCopyForReadOnlyClasspathResources() throws Exception { @Test public void shouldUseCopyOnlyWithReadOnlyClasspathResources() { String resource = "/test_copy_to_container.txt"; - GenericContainer container = new GenericContainer<>() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withClasspathResourceMapping(resource, "/readOnly", BindMode.READ_ONLY) .withClasspathResourceMapping(resource, "/readOnlyNoSelinux", BindMode.READ_ONLY) @@ -64,7 +65,7 @@ public void shouldUseCopyOnlyWithReadOnlyClasspathResources() { public void shouldCreateFoldersStructureWithCopy() throws Exception { String resource = "/test_copy_to_container.txt"; try ( - GenericContainer container = new GenericContainer<>() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withCommand("sleep", "3000") .withClasspathResourceMapping(resource, "/a/b/c/file", BindMode.READ_ONLY) ) { diff --git a/core/src/test/java/org/testcontainers/junit/DependenciesTest.java b/core/src/test/java/org/testcontainers/junit/DependenciesTest.java index 4f2ee01bc6d..bd82c58a7f7 100644 --- a/core/src/test/java/org/testcontainers/junit/DependenciesTest.java +++ b/core/src/test/java/org/testcontainers/junit/DependenciesTest.java @@ -16,6 +16,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import static org.testcontainers.TestImages.TINY_IMAGE; + public class DependenciesTest { @Test @@ -23,7 +25,7 @@ public void shouldWorkWithSimpleDependency() { InvocationCountingStartable startable = new InvocationCountingStartable(); try ( - GenericContainer container = new GenericContainer() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) .dependsOn(startable) ) { @@ -40,7 +42,7 @@ public void shouldWorkWithMutlipleDependencies() { InvocationCountingStartable startable2 = new InvocationCountingStartable(); try ( - GenericContainer container = new GenericContainer() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) .dependsOn(startable1, startable2) ) { @@ -56,7 +58,7 @@ public void shouldStartEveryTime() { InvocationCountingStartable startable = new InvocationCountingStartable(); try ( - GenericContainer container = new GenericContainer() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) .dependsOn(startable) ) { @@ -83,7 +85,7 @@ public void shouldStartTransitiveDependencies() { startable.getDependencies().add(transitiveStartable); try ( - GenericContainer container = new GenericContainer() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) .dependsOn(startable) ) { diff --git a/core/src/test/java/org/testcontainers/junit/DockerNetworkModeTest.java b/core/src/test/java/org/testcontainers/junit/DockerNetworkModeTest.java index 873160bdbc9..59c2a63127c 100644 --- a/core/src/test/java/org/testcontainers/junit/DockerNetworkModeTest.java +++ b/core/src/test/java/org/testcontainers/junit/DockerNetworkModeTest.java @@ -2,12 +2,13 @@ import com.github.dockerjava.api.model.NetworkSettings; import lombok.extern.slf4j.Slf4j; -import org.junit.*; +import org.junit.Test; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy; import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.testcontainers.TestImages.TINY_IMAGE; /** * Simple tests of named network modes - more may be possible, but may not be reproducible @@ -19,7 +20,7 @@ public class DockerNetworkModeTest { @Test public void testNoNetworkContainer() { try ( - GenericContainer container = new GenericContainer() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) .withCommand("true") .withNetworkMode("none") @@ -35,7 +36,7 @@ public void testNoNetworkContainer() { @Test public void testHostNetworkContainer() { try ( - GenericContainer container = new GenericContainer() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) .withCommand("true") .withNetworkMode("host") diff --git a/core/src/test/java/org/testcontainers/junit/FileOperationsTest.java b/core/src/test/java/org/testcontainers/junit/FileOperationsTest.java index 95de9ef1b85..5e12fafc064 100644 --- a/core/src/test/java/org/testcontainers/junit/FileOperationsTest.java +++ b/core/src/test/java/org/testcontainers/junit/FileOperationsTest.java @@ -12,6 +12,7 @@ import java.io.IOException; import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.testcontainers.TestImages.ALPINE_IMAGE; public class FileOperationsTest { @@ -21,7 +22,7 @@ public class FileOperationsTest { @Test public void copyFileToContainerFileTest() throws Exception { try ( - GenericContainer alpineCopyToContainer = new GenericContainer("alpine:3.2") + GenericContainer alpineCopyToContainer = new GenericContainer(ALPINE_IMAGE) .withCommand("top") ) { alpineCopyToContainer.start(); @@ -39,7 +40,7 @@ public void copyFileToContainerFileTest() throws Exception { @Test public void copyFileToContainerFolderTest() throws Exception { try ( - GenericContainer alpineCopyToContainer = new GenericContainer("alpine:3.2") + GenericContainer alpineCopyToContainer = new GenericContainer(ALPINE_IMAGE) .withCommand("top") ) { alpineCopyToContainer.start(); @@ -57,7 +58,7 @@ public void copyFileToContainerFolderTest() throws Exception { @Test public void copyFolderToContainerFolderTest() throws Exception { try ( - GenericContainer alpineCopyToContainer = new GenericContainer("alpine:3.2") + GenericContainer alpineCopyToContainer = new GenericContainer(ALPINE_IMAGE) .withCommand("top") ) { @@ -76,7 +77,7 @@ public void copyFolderToContainerFolderTest() throws Exception { @Test(expected = NotFoundException.class) public void copyFromContainerShouldFailBecauseNoFileTest() throws NotFoundException { try ( - GenericContainer alpineCopyToContainer = new GenericContainer("alpine:3.2") + GenericContainer alpineCopyToContainer = new GenericContainer(ALPINE_IMAGE) .withCommand("top") ) { alpineCopyToContainer.start(); @@ -87,7 +88,7 @@ public void copyFromContainerShouldFailBecauseNoFileTest() throws NotFoundExcept @Test public void shouldCopyFileFromContainerTest() throws IOException { try ( - GenericContainer alpineCopyToContainer = new GenericContainer("alpine:3.2") + GenericContainer alpineCopyToContainer = new GenericContainer(ALPINE_IMAGE) .withCommand("top") ) { diff --git a/core/src/test/java/org/testcontainers/junit/FixedHostPortContainerTest.java b/core/src/test/java/org/testcontainers/junit/FixedHostPortContainerTest.java index 5fe49756ba1..34c039b4fd3 100644 --- a/core/src/test/java/org/testcontainers/junit/FixedHostPortContainerTest.java +++ b/core/src/test/java/org/testcontainers/junit/FixedHostPortContainerTest.java @@ -1,8 +1,5 @@ package org.testcontainers.junit; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; - import com.google.common.util.concurrent.Uninterruptibles; import org.junit.Test; import org.rnorth.ducttape.unreliables.Unreliables; @@ -15,6 +12,10 @@ import java.net.Socket; import java.util.concurrent.TimeUnit; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.testcontainers.TestImages.TINY_IMAGE; + /** * Test of {@link FixedHostPortGenericContainer}. Note that this is not an example of typical use (usually, a container * should be a field on the test class annotated with @Rule or @TestRule). Instead, here, the lifecycle of the container @@ -46,7 +47,7 @@ public void testFixedHostPortMapping() throws IOException { // first find a free port on the docker host that will work for testing final Integer unusedHostPort; try ( - final GenericContainer echoServer = new GenericContainer<>(TEST_IMAGE) + final GenericContainer echoServer = new GenericContainer(TINY_IMAGE) .withExposedPorts(TEST_PORT) .withCommand("/bin/sh", "-c", HTTP_ECHO_CMD) ) { diff --git a/core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java b/core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java index b450244a84d..c13421029e0 100644 --- a/core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java +++ b/core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java @@ -6,10 +6,19 @@ import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; -import com.rabbitmq.client.*; +import com.rabbitmq.client.AMQP; +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.ConnectionFactory; +import com.rabbitmq.client.DefaultConsumer; +import com.rabbitmq.client.Envelope; import org.apache.commons.io.FileUtils; import org.bson.Document; -import org.junit.*; +import org.junit.Assume; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; import org.rnorth.ducttape.RetryCountExceededException; import org.rnorth.ducttape.unreliables.Unreliables; import org.testcontainers.containers.Container; @@ -18,7 +27,13 @@ import org.testcontainers.utility.Base58; import org.testcontainers.utility.TestEnvironment; -import java.io.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; import java.net.Socket; import java.time.Duration; import java.util.Arrays; @@ -30,7 +45,16 @@ import static java.util.Collections.singletonMap; import static org.hamcrest.CoreMatchers.equalTo; -import static org.rnorth.visibleassertions.VisibleAssertions.*; +import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.rnorth.visibleassertions.VisibleAssertions.assertFalse; +import static org.rnorth.visibleassertions.VisibleAssertions.assertThat; +import static org.rnorth.visibleassertions.VisibleAssertions.assertThrows; +import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.testcontainers.TestImages.ALPINE_IMAGE; +import static org.testcontainers.TestImages.MONGODB_IMAGE; +import static org.testcontainers.TestImages.RABBITMQ_IMAGE; +import static org.testcontainers.TestImages.REDIS_IMAGE; +import static org.testcontainers.TestImages.TINY_IMAGE; import static org.testcontainers.containers.BindMode.READ_ONLY; import static org.testcontainers.containers.BindMode.READ_WRITE; import static org.testcontainers.containers.SelinuxContext.SHARED; @@ -47,6 +71,7 @@ public class GenericContainerRuleTest { private static final int RABBITMQ_PORT = 5672; private static final int MONGO_PORT = 27017; + /* * Test data setup */ @@ -61,29 +86,27 @@ public static void setupContent() throws FileNotFoundException { * Redis */ @ClassRule - public static GenericContainer redis = new GenericContainer("redis:3.0.2") + public static GenericContainer redis = new GenericContainer<>(REDIS_IMAGE) .withExposedPorts(REDIS_PORT); /** * RabbitMQ */ @ClassRule - public static GenericContainer rabbitMq = new GenericContainer("rabbitmq:3.5.3") + public static GenericContainer rabbitMq = new GenericContainer<>(RABBITMQ_IMAGE) .withExposedPorts(RABBITMQ_PORT); - /** * MongoDB */ @ClassRule - public static GenericContainer mongo = new GenericContainer("mongo:3.1.5") + public static GenericContainer mongo = new GenericContainer<>(MONGODB_IMAGE) .withExposedPorts(MONGO_PORT); - /** * Pass an environment variable to the container, then run a shell script that exposes the variable in a quick and * dirty way for testing. */ @ClassRule - public static GenericContainer alpineEnvVar = new GenericContainer<>("alpine:3.2") + public static GenericContainer alpineEnvVar = new GenericContainer<>(ALPINE_IMAGE) .withExposedPorts(80) .withEnv("MAGIC_NUMBER", "4") .withEnv("MAGIC_NUMBER", oldValue -> oldValue.orElse("") + "2") @@ -94,7 +117,7 @@ public static void setupContent() throws FileNotFoundException { * dirty way for testing. */ @ClassRule - public static GenericContainer alpineEnvVarFromMap = new GenericContainer("alpine:3.2") + public static GenericContainer alpineEnvVarFromMap = new GenericContainer<>(ALPINE_IMAGE) .withExposedPorts(80) .withEnv(ImmutableMap.of( "FIRST", "42", @@ -106,7 +129,7 @@ public static void setupContent() throws FileNotFoundException { * Map a file on the classpath to a file in the container, and then expose the content for testing. */ @ClassRule - public static GenericContainer alpineClasspathResource = new GenericContainer("alpine:3.2") + public static GenericContainer alpineClasspathResource = new GenericContainer<>(ALPINE_IMAGE) .withExposedPorts(80) .withClasspathResourceMapping("mappable-resource/test-resource.txt", "/content.txt", READ_ONLY) .withCommand("/bin/sh", "-c", "while true; do cat /content.txt | nc -l -p 80; done"); @@ -115,7 +138,7 @@ public static void setupContent() throws FileNotFoundException { * Map a file on the classpath to a file in the container, and then expose the content for testing. */ @ClassRule - public static GenericContainer alpineClasspathResourceSelinux = new GenericContainer("alpine:3.2") + public static GenericContainer alpineClasspathResourceSelinux = new GenericContainer<>(ALPINE_IMAGE) .withExposedPorts(80) .withClasspathResourceMapping("mappable-resource/test-resource.txt", "/content.txt", READ_WRITE, SHARED) .withCommand("/bin/sh", "-c", "while true; do cat /content.txt | nc -l -p 80; done"); @@ -124,14 +147,16 @@ public static void setupContent() throws FileNotFoundException { * Create a container with an extra host entry and expose the content of /etc/hosts for testing. */ @ClassRule - public static GenericContainer alpineExtrahost = new GenericContainer("alpine:3.2") + public static GenericContainer alpineExtrahost = new GenericContainer<>(ALPINE_IMAGE) .withExposedPorts(80) .withExtraHost("somehost", "192.168.1.10") .withCommand("/bin/sh", "-c", "while true; do cat /etc/hosts | nc -l -p 80; done"); @Test public void testIsRunning() { - try (GenericContainer container = new GenericContainer().withCommand("top")) { + try ( + GenericContainer container = new GenericContainer<>(TINY_IMAGE) + .withCommand("top")) { assertFalse("Container is not started and not running", container.isRunning()); container.start(); assertTrue("Container is started and running", container.isRunning()); @@ -141,7 +166,7 @@ public void testIsRunning() { @Test public void withTmpFsTest() throws Exception { try ( - GenericContainer container = new GenericContainer() + GenericContainer container = new GenericContainer<>(TINY_IMAGE) .withCommand("top") .withTmpFs(singletonMap("/testtmpfs", "rw")) ) { @@ -222,7 +247,7 @@ public void environmentFromMapTest() throws IOException { @Test public void customLabelTest() { - try (final GenericContainer alpineCustomLabel = new GenericContainer("alpine:3.2") + try (final GenericContainer alpineCustomLabel = new GenericContainer<>(ALPINE_IMAGE) .withLabel("our.custom", "label") .withCommand("top")) { @@ -240,7 +265,7 @@ public void exceptionThrownWhenTryingToOverrideTestcontainersLabels() { assertThrows("When trying to overwrite an 'org.testcontainers' label, withLabel() throws an exception", IllegalArgumentException.class, () -> { - new GenericContainer("alpine:3.2") + new GenericContainer<>(ALPINE_IMAGE) .withLabel("org.testcontainers.foo", "false"); } ); @@ -262,7 +287,7 @@ public void customClasspathResourceMappingWithSelinuxTest() throws IOException { } @Test - public void exceptionThrownWhenMappedPortNotFound() throws IOException { + public void exceptionThrownWhenMappedPortNotFound() { assertThrows("When the requested port is not mapped, getMappedPort() throws an exception", IllegalArgumentException.class, () -> { @@ -279,10 +304,10 @@ protected static void writeStringToFile(File contentFolder, String filename, Str } @Test @Ignore //TODO investigate intermittent failures - public void failFastWhenContainerHaltsImmediately() throws Exception { + public void failFastWhenContainerHaltsImmediately() { long startingTimeMs = System.currentTimeMillis(); - final GenericContainer failsImmediately = new GenericContainer("alpine:3.2") + final GenericContainer failsImmediately = new GenericContainer<>(ALPINE_IMAGE) .withCommand("/bin/sh", "-c", "return false") .withMinimumRunningDuration(Duration.ofMillis(100)); @@ -346,7 +371,7 @@ public void createContainerCmdHookTest() { // Use random name to avoid the conflicts between the tests String randomName = Base58.randomString(5); try( - GenericContainer container = new GenericContainer<>("redis:3.0.2") + GenericContainer container = new GenericContainer<>(REDIS_IMAGE) .withCommand("redis-server", "--help") .withCreateContainerCmdModifier(cmd -> cmd.withName("overrideMe")) // Preserves the order @@ -390,7 +415,7 @@ public void addingExposedPortTwiceShouldNotFail() { @Test public void sharedMemorySetTest() { - try (GenericContainer containerWithSharedMemory = new GenericContainer() + try (GenericContainer containerWithSharedMemory = new GenericContainer<>(TINY_IMAGE) .withSharedMemorySize(42L * FileUtils.ONE_MB) .withStartupCheckStrategy(new OneShotStartupCheckStrategy())) { diff --git a/core/src/test/java/org/testcontainers/junit/NonExistentImagePullTest.java b/core/src/test/java/org/testcontainers/junit/NonExistentImagePullTest.java index d842829b4b6..95047779551 100644 --- a/core/src/test/java/org/testcontainers/junit/NonExistentImagePullTest.java +++ b/core/src/test/java/org/testcontainers/junit/NonExistentImagePullTest.java @@ -3,6 +3,7 @@ import org.junit.Test; import org.testcontainers.containers.ContainerFetchException; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import static org.rnorth.visibleassertions.VisibleAssertions.assertThrows; @@ -16,7 +17,7 @@ public void pullingNonExistentImageFailsGracefully() { assertThrows("Pulling a nonexistent container will cause an exception to be thrown", ContainerFetchException.class, () -> { - new GenericContainer("richnorth/nonexistent:latest").getDockerImageName(); + new GenericContainer<>(DockerImageName.parse("testcontainers/nonexistent:latest")).getDockerImageName(); }); } } diff --git a/core/src/test/java/org/testcontainers/junit/OutputStreamTest.java b/core/src/test/java/org/testcontainers/junit/OutputStreamTest.java index 83ba05be86e..649a0b56fc4 100644 --- a/core/src/test/java/org/testcontainers/junit/OutputStreamTest.java +++ b/core/src/test/java/org/testcontainers/junit/OutputStreamTest.java @@ -14,7 +14,10 @@ import java.util.concurrent.TimeoutException; import java.util.function.Consumer; -import static org.rnorth.visibleassertions.VisibleAssertions.*; +import static org.rnorth.visibleassertions.VisibleAssertions.assertFalse; +import static org.rnorth.visibleassertions.VisibleAssertions.assertThrows; +import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.testcontainers.TestImages.ALPINE_IMAGE; import static org.testcontainers.containers.output.OutputFrame.OutputType.STDOUT; /** @@ -23,7 +26,7 @@ public class OutputStreamTest { @Rule - public GenericContainer container = new GenericContainer("alpine:3.2") + public GenericContainer container = new GenericContainer(ALPINE_IMAGE) .withCommand("ping -c 5 127.0.0.1"); private static final Logger LOGGER = LoggerFactory.getLogger(OutputStreamTest.class); diff --git a/core/src/test/java/org/testcontainers/junit/OutputStreamWithTTYTest.java b/core/src/test/java/org/testcontainers/junit/OutputStreamWithTTYTest.java index 0e7b66534b7..b15f63f4158 100644 --- a/core/src/test/java/org/testcontainers/junit/OutputStreamWithTTYTest.java +++ b/core/src/test/java/org/testcontainers/junit/OutputStreamWithTTYTest.java @@ -15,14 +15,17 @@ import java.util.concurrent.TimeoutException; import java.util.function.Consumer; -import static org.rnorth.visibleassertions.VisibleAssertions.*; +import static org.rnorth.visibleassertions.VisibleAssertions.assertFalse; +import static org.rnorth.visibleassertions.VisibleAssertions.assertThrows; +import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.testcontainers.TestImages.ALPINE_IMAGE; import static org.testcontainers.containers.output.OutputFrame.OutputType.STDOUT; @Slf4j public class OutputStreamWithTTYTest { @Rule - public GenericContainer container = new GenericContainer<>("alpine:3.2") + public GenericContainer container = new GenericContainer<>(ALPINE_IMAGE) .withCommand("ls -1") .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) .withCreateContainerCmdModifier(command -> command.withTty(true)); diff --git a/core/src/test/java/org/testcontainers/junit/WorkingDirectoryTest.java b/core/src/test/java/org/testcontainers/junit/WorkingDirectoryTest.java index 30230cc12ff..b23ddf2ca1c 100644 --- a/core/src/test/java/org/testcontainers/junit/WorkingDirectoryTest.java +++ b/core/src/test/java/org/testcontainers/junit/WorkingDirectoryTest.java @@ -6,6 +6,7 @@ import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy; import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.testcontainers.TestImages.ALPINE_IMAGE; /** * Created by rnorth on 26/07/2016. @@ -13,7 +14,7 @@ public class WorkingDirectoryTest { @ClassRule - public static GenericContainer container = new GenericContainer("alpine:3.2") + public static GenericContainer container = new GenericContainer(ALPINE_IMAGE) .withWorkingDirectory("/etc") .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) .withCommand("ls", "-al"); diff --git a/core/src/test/java/org/testcontainers/junit/wait/strategy/AbstractWaitStrategyTest.java b/core/src/test/java/org/testcontainers/junit/wait/strategy/AbstractWaitStrategyTest.java index 3d3c2f0606d..480536a54ef 100644 --- a/core/src/test/java/org/testcontainers/junit/wait/strategy/AbstractWaitStrategyTest.java +++ b/core/src/test/java/org/testcontainers/junit/wait/strategy/AbstractWaitStrategyTest.java @@ -4,6 +4,7 @@ import org.junit.Before; import org.rnorth.ducttape.RetryCountExceededException; import org.rnorth.visibleassertions.VisibleAssertions; +import org.testcontainers.TestImages; import org.testcontainers.containers.ContainerLaunchException; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.WaitStrategy; @@ -20,7 +21,6 @@ */ public abstract class AbstractWaitStrategyTest { static final long WAIT_TIMEOUT_MILLIS = 3000; - static final String IMAGE_NAME = "alpine:3.7"; /** * Indicates that the WaitStrategy has completed waiting successfully. @@ -38,36 +38,36 @@ public abstract class AbstractWaitStrategyTest { protected abstract W buildWaitStrategy(final AtomicBoolean ready); @Before - public void setUp() throws Exception { + public void setUp() { ready = new AtomicBoolean(false); } /** - * Starts a GenericContainer with the {@link #IMAGE_NAME} image, passing the given {@code shellCommand} as + * Starts a GenericContainer with the Alpine image, passing the given {@code shellCommand} as * a parameter to {@literal sh -c} (the container CMD). * * @param shellCommand the shell command to execute * @return the (unstarted) container */ - private GenericContainer startContainerWithCommand(String shellCommand) { + private GenericContainer startContainerWithCommand(String shellCommand) { return startContainerWithCommand(shellCommand, buildWaitStrategy(ready)); } /** - * Starts a GenericContainer with the {@link #IMAGE_NAME} image, passing the given {@code shellCommand} as + * Starts a GenericContainer with the Alpine image, passing the given {@code shellCommand} as * a parameter to {@literal sh -c} (the container CMD) and apply a give wait strategy. * Note that the timeout will be overwritten if any with {@link #WAIT_TIMEOUT_MILLIS}. * @param shellCommand the shell command to execute * @param waitStrategy The wait strategy to apply * @return the (unstarted) container */ - protected GenericContainer startContainerWithCommand(String shellCommand, WaitStrategy waitStrategy) { + protected GenericContainer startContainerWithCommand(String shellCommand, WaitStrategy waitStrategy) { return startContainerWithCommand(shellCommand, waitStrategy, 8080); } - protected GenericContainer startContainerWithCommand(String shellCommand, WaitStrategy waitStrategy, Integer... ports) { + protected GenericContainer startContainerWithCommand(String shellCommand, WaitStrategy waitStrategy, Integer... ports) { // apply WaitStrategy to container - return new GenericContainer(IMAGE_NAME) + return new GenericContainer<>(TestImages.ALPINE_IMAGE) .withExposedPorts(ports) .withCommand("sh", "-c", shellCommand) .waitingFor(waitStrategy.withStartupTimeout(Duration.ofMillis(WAIT_TIMEOUT_MILLIS))); @@ -98,7 +98,7 @@ protected void waitUntilReadyAndTimeout(String shellCommand) { * * @param container the container to start */ - protected void waitUntilReadyAndTimeout(GenericContainer container) { + protected void waitUntilReadyAndTimeout(GenericContainer container) { // start() blocks until successful or timeout VisibleAssertions.assertThrows("an exception is thrown when timeout occurs (" + WAIT_TIMEOUT_MILLIS + "ms)", ContainerLaunchException.class, @@ -111,7 +111,7 @@ protected void waitUntilReadyAndTimeout(GenericContainer container) { * * @param container the container to start */ - protected void waitUntilReadyAndSucceed(GenericContainer container) { + protected void waitUntilReadyAndSucceed(GenericContainer container) { // start() blocks until successful or timeout container.start(); diff --git a/core/src/test/java/org/testcontainers/junit/wait/strategy/HostPortWaitStrategyTest.java b/core/src/test/java/org/testcontainers/junit/wait/strategy/HostPortWaitStrategyTest.java index d715b25aaf6..5c7d37a7da3 100644 --- a/core/src/test/java/org/testcontainers/junit/wait/strategy/HostPortWaitStrategyTest.java +++ b/core/src/test/java/org/testcontainers/junit/wait/strategy/HostPortWaitStrategyTest.java @@ -2,6 +2,7 @@ import org.junit.ClassRule; import org.junit.Test; +import org.testcontainers.TestImages; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; @@ -15,10 +16,8 @@ */ public class HostPortWaitStrategyTest { - private static final String IMAGE_NAME = "alpine:3.7"; - @ClassRule - public static GenericContainer container = new GenericContainer(IMAGE_NAME).withExposedPorts() + public static GenericContainer container = new GenericContainer<>(TestImages.ALPINE_IMAGE).withExposedPorts() .withCommand("sh", "-c", "while true; do nc -lp 8080; done") .withExposedPorts(8080) .waitingFor(Wait.forListeningPort().withStartupTimeout(Duration.ofSeconds(10))); diff --git a/core/src/test/java/org/testcontainers/utility/AuthenticatedImagePullTest.java b/core/src/test/java/org/testcontainers/utility/AuthenticatedImagePullTest.java index 3986255f248..0afb4d956a1 100644 --- a/core/src/test/java/org/testcontainers/utility/AuthenticatedImagePullTest.java +++ b/core/src/test/java/org/testcontainers/utility/AuthenticatedImagePullTest.java @@ -28,6 +28,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.testcontainers.TestImages.DOCKER_REGISTRY_IMAGE; /** * This test checks the integration between Testcontainers and an authenticated registry, but uses @@ -45,7 +46,7 @@ public class AuthenticatedImagePullTest { @ClassRule public static GenericContainer authenticatedRegistry = new GenericContainer<>(new ImageFromDockerfile() .withDockerfileFromBuilder(builder -> { - builder.from("registry:2.7.0") + builder.from(DOCKER_REGISTRY_IMAGE.asCanonicalNameString()) .run("htpasswd -Bbn testuser notasecret > /htpasswd") .env("REGISTRY_AUTH", "htpasswd") .env("REGISTRY_AUTH_HTPASSWD_PATH", "/htpasswd") @@ -69,7 +70,7 @@ public static void setUp() throws InterruptedException { testImageName = testRegistryAddress + "/alpine"; testImageNameWithTag = testImageName + ":latest"; - final DockerImageName expectedName = new DockerImageName(testImageNameWithTag); + final DockerImageName expectedName = DockerImageName.parse(testImageNameWithTag); final AuthConfig authConfig = new AuthConfig() .withUsername("testuser") .withPassword("notasecret") @@ -99,7 +100,7 @@ public static void tearDown() { @Test public void testThatAuthLocatorIsUsedForContainerCreation() { // actually start a container, which will require an authenticated pull - try (final GenericContainer container = new GenericContainer<>(testImageNameWithTag) + try (final GenericContainer container = new GenericContainer<>(DockerImageName.parse(testImageNameWithTag)) .withCommand("/bin/sh", "-c", "sleep 10")) { container.start(); @@ -165,7 +166,7 @@ private Path getLocalTempFile(String s) throws IOException { private static void putImageInRegistry() throws InterruptedException { // It doesn't matter which image we use for this test, but use one that's likely to have been pulled already - final String dummySourceImage = TestcontainersConfiguration.getInstance().getRyukImage(); + final String dummySourceImage = TestcontainersConfiguration.getInstance().getRyukDockerImageName().asCanonicalNameString(); client.pullImageCmd(dummySourceImage) .exec(new PullImageResultCallback()) diff --git a/core/src/test/java/org/testcontainers/utility/DockerImageNameTest.java b/core/src/test/java/org/testcontainers/utility/DockerImageNameTest.java index 54488773652..b0ed9428a5d 100644 --- a/core/src/test/java/org/testcontainers/utility/DockerImageNameTest.java +++ b/core/src/test/java/org/testcontainers/utility/DockerImageNameTest.java @@ -35,7 +35,7 @@ public static String[] getNames() { @Test public void testValidNameAccepted() { - new DockerImageName(imageName).assertValid(); + DockerImageName.parse(imageName).assertValid(); } } @@ -56,7 +56,7 @@ public static String[] getNames() { @Test(expected = IllegalArgumentException.class) public void testInvalidNameRejected() { - new DockerImageName(imageName).assertValid(); + DockerImageName.parse(imageName).assertValid(); } } @@ -66,12 +66,18 @@ public static class Parsing { @Parameterized.Parameters(name = "{0}{1}{2}{3}{4}") public static String[][] getNames() { return new String[][]{ + {"", "", "myname", ":", null}, {"", "", "myname", ":", "latest"}, + {"", "", "repo/myname", ":", null}, {"", "", "repo/myname", ":", "latest"}, + {"registry.foo.com:1234", "/", "my-name", ":", null}, {"registry.foo.com:1234", "/", "my-name", ":", "1.0"}, {"registry.foo.com", "/", "my-name", ":", "1.0"}, + {"registry.foo.com:1234", "/", "repo_here/my-name", ":", null}, {"registry.foo.com:1234", "/", "repo_here/my-name", ":", "1.0"}, + {"1.2.3.4:1234", "/", "repo_here/my-name", ":", null}, {"1.2.3.4:1234", "/", "repo_here/my-name", ":", "1.0"}, + {"1.2.3.4:1234", "/", "my-name", ":", null}, {"1.2.3.4:1234", "/", "my-name", ":", "1.0"}, {"", "", "myname", "@", "sha256:1234abcd1234abcd1234abcd1234abcd"}, {"", "", "repo/myname", "@", "sha256:1234abcd1234abcd1234abcd1234abcd"}, @@ -98,22 +104,38 @@ public static String[][] getNames() { @Test public void testParsing() { final String unversionedPart = registry + registrySeparator + repo; - final String combined = unversionedPart + versionSeparator + version; + + String combined; + String canonicalName; + if (version != null) { + combined = unversionedPart + versionSeparator + version; + canonicalName = unversionedPart + versionSeparator + version; + } else { + combined = unversionedPart; + canonicalName = unversionedPart + ":latest"; + } VisibleAssertions.context("For " + combined); VisibleAssertions.context("Using single-arg constructor:", 2); - final DockerImageName imageName = new DockerImageName(combined); + final DockerImageName imageName = DockerImageName.parse(combined); assertEquals(combined + " has registry address: " + registry, registry, imageName.getRegistry()); assertEquals(combined + " has unversioned part: " + unversionedPart, unversionedPart, imageName.getUnversionedPart()); - assertEquals(combined + " has version part: " + version, version, imageName.getVersionPart()); - - VisibleAssertions.context("Using two-arg constructor:", 2); - - final DockerImageName imageNameFromSecondaryConstructor = new DockerImageName(unversionedPart, version); - assertEquals(combined + " has registry address: " + registry, registry, imageNameFromSecondaryConstructor.getRegistry()); - assertEquals(combined + " has unversioned part: " + unversionedPart, unversionedPart, imageNameFromSecondaryConstructor.getUnversionedPart()); - assertEquals(combined + " has version part: " + version, version, imageNameFromSecondaryConstructor.getVersionPart()); + if (version != null) { + assertEquals(combined + " has version part: " + version, version, imageName.getVersionPart()); + } else { + assertEquals(combined + " has implicit version: latest", "latest", imageName.getVersionPart()); + } + assertEquals(combined + " has canonical name: " + canonicalName, canonicalName, imageName.asCanonicalNameString()); + + if (version != null) { + VisibleAssertions.context("Using two-arg constructor:", 2); + + final DockerImageName imageNameFromSecondaryConstructor = new DockerImageName(unversionedPart, version); + assertEquals(combined + " has registry address: " + registry, registry, imageNameFromSecondaryConstructor.getRegistry()); + assertEquals(combined + " has unversioned part: " + unversionedPart, unversionedPart, imageNameFromSecondaryConstructor.getUnversionedPart()); + assertEquals(combined + " has version part: " + version, version, imageNameFromSecondaryConstructor.getVersionPart()); + } } } } diff --git a/core/src/test/java/org/testcontainers/utility/RegistryAuthLocatorTest.java b/core/src/test/java/org/testcontainers/utility/RegistryAuthLocatorTest.java index e1cb595e903..a5e5ab4260d 100644 --- a/core/src/test/java/org/testcontainers/utility/RegistryAuthLocatorTest.java +++ b/core/src/test/java/org/testcontainers/utility/RegistryAuthLocatorTest.java @@ -18,7 +18,7 @@ public class RegistryAuthLocatorTest { public void lookupAuthConfigWithoutCredentials() throws URISyntaxException { final RegistryAuthLocator authLocator = createTestAuthLocator("config-empty.json"); - final AuthConfig authConfig = authLocator.lookupAuthConfig(new DockerImageName("unauthenticated.registry.org/org/repo"), new AuthConfig()); + final AuthConfig authConfig = authLocator.lookupAuthConfig(DockerImageName.parse("unauthenticated.registry.org/org/repo"), new AuthConfig()); assertEquals("Default docker registry URL is set on auth config", "https://index.docker.io/v1/", authConfig.getRegistryAddress()); assertNull("No username is set", authConfig.getUsername()); @@ -29,7 +29,7 @@ public void lookupAuthConfigWithoutCredentials() throws URISyntaxException { public void lookupAuthConfigWithBasicAuthCredentials() throws URISyntaxException { final RegistryAuthLocator authLocator = createTestAuthLocator("config-basic-auth.json"); - final AuthConfig authConfig = authLocator.lookupAuthConfig(new DockerImageName("registry.example.com/org/repo"), new AuthConfig()); + final AuthConfig authConfig = authLocator.lookupAuthConfig(DockerImageName.parse("registry.example.com/org/repo"), new AuthConfig()); assertEquals("Default docker registry URL is set on auth config", "https://registry.example.com", authConfig.getRegistryAddress()); assertEquals("Username is set", "user", authConfig.getUsername()); @@ -40,7 +40,7 @@ public void lookupAuthConfigWithBasicAuthCredentials() throws URISyntaxException public void lookupAuthConfigWithJsonKeyCredentials() throws URISyntaxException { final RegistryAuthLocator authLocator = createTestAuthLocator("config-with-json-key.json"); - final AuthConfig authConfig = authLocator.lookupAuthConfig(new DockerImageName("registry.example.com/org/repo"), new AuthConfig()); + final AuthConfig authConfig = authLocator.lookupAuthConfig(DockerImageName.parse("registry.example.com/org/repo"), new AuthConfig()); assertEquals("Default docker registry URL is set on auth config", "https://registry.example.com", authConfig.getRegistryAddress()); assertEquals("Username is set", "_json_key", authConfig.getUsername()); @@ -51,7 +51,7 @@ public void lookupAuthConfigWithJsonKeyCredentials() throws URISyntaxException { public void lookupAuthConfigUsingStore() throws URISyntaxException { final RegistryAuthLocator authLocator = createTestAuthLocator("config-with-store.json"); - final AuthConfig authConfig = authLocator.lookupAuthConfig(new DockerImageName("registry.example.com/org/repo"), new AuthConfig()); + final AuthConfig authConfig = authLocator.lookupAuthConfig(DockerImageName.parse("registry.example.com/org/repo"), new AuthConfig()); assertEquals("Correct server URL is obtained from a credential store", "url", authConfig.getRegistryAddress()); assertEquals("Correct username is obtained from a credential store", "username", authConfig.getUsername()); @@ -62,7 +62,7 @@ public void lookupAuthConfigUsingStore() throws URISyntaxException { public void lookupAuthConfigUsingHelper() throws URISyntaxException { final RegistryAuthLocator authLocator = createTestAuthLocator("config-with-helper.json"); - final AuthConfig authConfig = authLocator.lookupAuthConfig(new DockerImageName("registry.example.com/org/repo"), new AuthConfig()); + final AuthConfig authConfig = authLocator.lookupAuthConfig(DockerImageName.parse("registry.example.com/org/repo"), new AuthConfig()); assertEquals("Correct server URL is obtained from a credential store", "url", authConfig.getRegistryAddress()); assertEquals("Correct username is obtained from a credential store", "username", authConfig.getUsername()); @@ -73,7 +73,7 @@ public void lookupAuthConfigUsingHelper() throws URISyntaxException { public void lookupAuthConfigUsingHelperWithToken() throws URISyntaxException { final RegistryAuthLocator authLocator = createTestAuthLocator("config-with-helper-using-token.json"); - final AuthConfig authConfig = authLocator.lookupAuthConfig(new DockerImageName("registrytoken.example.com/org/repo"), new AuthConfig()); + final AuthConfig authConfig = authLocator.lookupAuthConfig(DockerImageName.parse("registrytoken.example.com/org/repo"), new AuthConfig()); assertEquals("Correct identitytoken is obtained from a credential store", "secret", authConfig.getIdentitytoken()); } @@ -82,7 +82,7 @@ public void lookupAuthConfigUsingHelperWithToken() throws URISyntaxException { public void lookupUsingHelperEmptyAuth() throws URISyntaxException { final RegistryAuthLocator authLocator = createTestAuthLocator("config-empty-auth-with-helper.json"); - final AuthConfig authConfig = authLocator.lookupAuthConfig(new DockerImageName("registry.example.com/org/repo"), new AuthConfig()); + final AuthConfig authConfig = authLocator.lookupAuthConfig(DockerImageName.parse("registry.example.com/org/repo"), new AuthConfig()); assertEquals("Correct server URL is obtained from a credential store", "url", authConfig.getRegistryAddress()); assertEquals("Correct username is obtained from a credential store", "username", authConfig.getUsername()); @@ -93,7 +93,7 @@ public void lookupUsingHelperEmptyAuth() throws URISyntaxException { public void lookupNonEmptyAuthWithHelper() throws URISyntaxException { final RegistryAuthLocator authLocator = createTestAuthLocator("config-existing-auth-with-helper.json"); - final AuthConfig authConfig = authLocator.lookupAuthConfig(new DockerImageName("registry.example.com/org/repo"), new AuthConfig()); + final AuthConfig authConfig = authLocator.lookupAuthConfig(DockerImageName.parse("registry.example.com/org/repo"), new AuthConfig()); assertEquals("Correct server URL is obtained from a credential helper", "url", authConfig.getRegistryAddress()); assertEquals("Correct username is obtained from a credential helper", "username", authConfig.getUsername()); @@ -105,7 +105,7 @@ public void lookupAuthConfigWithCredentialsNotFound() throws URISyntaxException Map notFoundMessagesReference = new HashMap<>(); final RegistryAuthLocator authLocator = createTestAuthLocator("config-with-store.json", notFoundMessagesReference); - DockerImageName dockerImageName = new DockerImageName("registry2.example.com/org/repo"); + DockerImageName dockerImageName = DockerImageName.parse("registry2.example.com/org/repo"); final AuthConfig authConfig = authLocator.lookupAuthConfig(dockerImageName, new AuthConfig()); assertNull("No username should have been obtained from a credential store", authConfig.getUsername()); @@ -124,7 +124,7 @@ public void lookupAuthConfigWithCredentialsNotFound() throws URISyntaxException public void lookupAuthConfigWithCredStoreEmpty() throws URISyntaxException { final RegistryAuthLocator authLocator = createTestAuthLocator("config-with-store-empty.json"); - DockerImageName dockerImageName = new DockerImageName("registry2.example.com/org/repo"); + DockerImageName dockerImageName = DockerImageName.parse("registry2.example.com/org/repo"); final AuthConfig authConfig = authLocator.lookupAuthConfig(dockerImageName, new AuthConfig()); assertNull("CredStore field will be ignored, because value is blank", authConfig.getAuth()); diff --git a/docs/examples/junit4/generic/src/test/java/generic/CmdModifierTest.java b/docs/examples/junit4/generic/src/test/java/generic/CmdModifierTest.java index 172a821b178..f49e6a26565 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/CmdModifierTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/CmdModifierTest.java @@ -4,6 +4,7 @@ import org.junit.Test; import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import java.io.IOException; @@ -13,7 +14,7 @@ public class CmdModifierTest { // hostname { @Rule - public GenericContainer theCache = new GenericContainer<>("redis:3.0.2") + public GenericContainer theCache = new GenericContainer<>(DockerImageName.parse("redis:3.0.2")) .withCreateContainerCmdModifier(cmd -> cmd.withHostName("the-cache")); // } @@ -22,7 +23,7 @@ public class CmdModifierTest { private long memorySwapInBytes = 12 * 1024 * 1024; @Rule - public GenericContainer memoryLimitedRedis = new GenericContainer<>("redis:3.0.2") + public GenericContainer memoryLimitedRedis = new GenericContainer<>(DockerImageName.parse("redis:3.0.2")) .withCreateContainerCmdModifier(cmd -> cmd.getHostConfig() .withMemory(memoryInBytes) .withMemorySwap(memorySwapInBytes) diff --git a/docs/examples/junit4/generic/src/test/java/generic/CommandsTest.java b/docs/examples/junit4/generic/src/test/java/generic/CommandsTest.java index 486464c7dda..23b265c26fa 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/CommandsTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/CommandsTest.java @@ -3,13 +3,14 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import static org.junit.Assert.assertTrue; public class CommandsTest { @Rule // startupCommand { - public GenericContainer redisWithCustomPort = new GenericContainer("redis:5.0") + public GenericContainer redisWithCustomPort = new GenericContainer(DockerImageName.parse("redis:5.0")) .withCommand("redis-server --port 7777") // } .withExposedPorts(7777); diff --git a/docs/examples/junit4/generic/src/test/java/generic/ContainerCreationTest.java b/docs/examples/junit4/generic/src/test/java/generic/ContainerCreationTest.java index 19a40a7c43a..b0e8c98a0e4 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/ContainerCreationTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/ContainerCreationTest.java @@ -3,28 +3,35 @@ import org.junit.ClassRule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import static org.junit.Assert.assertTrue; public class ContainerCreationTest { + // simple { + public static final DockerImageName REDIS_IMAGE = DockerImageName.parse("redis:3.0.2"); + // } + // simple { @ClassRule - public static GenericContainer redis = - new GenericContainer("redis:3.0.2") + public static GenericContainer redis = + new GenericContainer<>(REDIS_IMAGE) .withExposedPorts(6379); // } + public static final DockerImageName ALPINE_IMAGE = DockerImageName.parse("alpine:3.2"); + // withOptions { - // Set up a plain OS container and customize environment, - // command and exposed ports. This just listens on port 80 + // Set up a plain OS container and customize environment, + // command and exposed ports. This just listens on port 80 // and always returns '42' @ClassRule - public static GenericContainer alpine = - new GenericContainer("alpine:3.2") + public static GenericContainer alpine = + new GenericContainer<>(ALPINE_IMAGE) .withExposedPorts(80) .withEnv("MAGIC_NUMBER", "42") - .withCommand("/bin/sh", "-c", + .withCommand("/bin/sh", "-c", "while true; do echo \"$MAGIC_NUMBER\" | nc -l -p 80; done"); // } diff --git a/docs/examples/junit4/generic/src/test/java/generic/ContainerLabelTest.java b/docs/examples/junit4/generic/src/test/java/generic/ContainerLabelTest.java index f8f26eaa5fe..ca0878e89d4 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/ContainerLabelTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/ContainerLabelTest.java @@ -1,13 +1,14 @@ package generic; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import java.util.HashMap; import java.util.Map; public class ContainerLabelTest { // single_label { - public GenericContainer containerWithLabel = new GenericContainer("alpine:3.6") + public GenericContainer containerWithLabel = new GenericContainer(DockerImageName.parse("alpine:3.6")) .withLabel("key", "value"); // } @@ -16,7 +17,7 @@ public class ContainerLabelTest { private Map mapOfLabels = new HashMap<>(); // populate map, e.g. mapOfLabels.put("key1", "value1"); - public GenericContainer containerWithMultipleLabels = new GenericContainer("alpine:3.6") + public GenericContainer containerWithMultipleLabels = new GenericContainer(DockerImageName.parse("alpine:3.6")) .withLabels(mapOfLabels); // } } diff --git a/docs/examples/junit4/generic/src/test/java/generic/ExecTest.java b/docs/examples/junit4/generic/src/test/java/generic/ExecTest.java index e160390c293..e35ae18af70 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/ExecTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/ExecTest.java @@ -4,6 +4,7 @@ import org.junit.Test; import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import java.io.IOException; @@ -12,7 +13,7 @@ public class ExecTest { @Rule - public GenericContainer container = new GenericContainer("alpine:3.6") + public GenericContainer container = new GenericContainer<>(DockerImageName.parse("alpine:3.6")) .withCommand("top"); @Test diff --git a/docs/examples/junit4/generic/src/test/java/generic/MultiplePortsExposedTest.java b/docs/examples/junit4/generic/src/test/java/generic/MultiplePortsExposedTest.java index f5a92423b6c..329fd8d8e19 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/MultiplePortsExposedTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/MultiplePortsExposedTest.java @@ -5,6 +5,7 @@ import org.slf4j.Logger; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; +import org.testcontainers.utility.DockerImageName; import static org.slf4j.LoggerFactory.getLogger; @@ -14,7 +15,7 @@ public class MultiplePortsExposedTest { @Rule // rule { - public GenericContainer container = new GenericContainer("orientdb:3.0.13") + public GenericContainer container = new GenericContainer(DockerImageName.parse("orientdb:3.0.13")) .withExposedPorts(2424, 2480) .withLogConsumer(new Slf4jLogConsumer(log)); // } diff --git a/docs/examples/junit4/generic/src/test/java/generic/WaitStrategiesTest.java b/docs/examples/junit4/generic/src/test/java/generic/WaitStrategiesTest.java index 0bb5eb40bc1..d45b1e28c47 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/WaitStrategiesTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/WaitStrategiesTest.java @@ -6,6 +6,7 @@ import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.containers.wait.strategy.WaitStrategy; +import org.testcontainers.utility.DockerImageName; import static org.junit.Assert.assertTrue; @@ -13,20 +14,20 @@ public class WaitStrategiesTest { @Rule // waitForNetworkListening { - public GenericContainer nginx = new GenericContainer("nginx:1.9.4") + public GenericContainer nginx = new GenericContainer(DockerImageName.parse("nginx:1.9.4")) .withExposedPorts(80); // } @Rule // waitForSimpleHttp { - public GenericContainer nginxWithHttpWait = new GenericContainer("nginx:1.9.4") + public GenericContainer nginxWithHttpWait = new GenericContainer(DockerImageName.parse("nginx:1.9.4")) .withExposedPorts(80) .waitingFor(Wait.forHttp("/")); // } @Rule // logMessageWait { - public GenericContainer containerWithLogWait = new GenericContainer("redis:5.0.3") + public GenericContainer containerWithLogWait = new GenericContainer(DockerImageName.parse("redis:5.0.3")) .withExposedPorts(6379) .waitingFor( Wait.forLogMessage(".*Ready to accept connections.*\\n", 1) diff --git a/docs/examples/junit4/generic/src/test/java/org/testcontainers/containers/startupcheck/StartupCheckStrategyTest.java b/docs/examples/junit4/generic/src/test/java/org/testcontainers/containers/startupcheck/StartupCheckStrategyTest.java index deef64bc59b..0e72efb5723 100644 --- a/docs/examples/junit4/generic/src/test/java/org/testcontainers/containers/startupcheck/StartupCheckStrategyTest.java +++ b/docs/examples/junit4/generic/src/test/java/org/testcontainers/containers/startupcheck/StartupCheckStrategyTest.java @@ -7,6 +7,7 @@ import org.junit.runners.Suite; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.WaitingConsumer; +import org.testcontainers.utility.DockerImageName; import java.time.Duration; import java.util.concurrent.TimeUnit; @@ -35,7 +36,7 @@ private static void waitForHello(GenericContainer container) throws TimeoutExcep public static class OneShotStrategyTest { @Rule // withOneShotStrategy { - public GenericContainer bboxWithOneShot = new GenericContainer("busybox:1.31.1") + public GenericContainer bboxWithOneShot = new GenericContainer<>(DockerImageName.parse("busybox:1.31.1")) .withCommand(String.format("echo %s", HELLO_TESTCONTAINERS)) .withStartupCheckStrategy( new OneShotStartupCheckStrategy().withTimeout(Duration.ofSeconds(3)) @@ -54,7 +55,7 @@ public void testCommandIsExecuted() { public static class IndefiniteOneShotStrategyTest { @Rule // withIndefiniteOneShotStrategy { - public GenericContainer bboxWithIndefiniteOneShot = new GenericContainer("busybox:1.31.1") + public GenericContainer bboxWithIndefiniteOneShot = new GenericContainer<>(DockerImageName.parse("busybox:1.31.1")) .withCommand("sh", "-c", String.format("sleep 5 && echo \"%s\"", HELLO_TESTCONTAINERS)) .withStartupCheckStrategy( new IndefiniteWaitOneShotStartupCheckStrategy() @@ -73,7 +74,7 @@ public void testCommandIsExecuted() { public static class MinimumDurationStrategyTest { @Rule // withMinimumDurationStrategy { - public GenericContainer bboxWithMinimumDuration = new GenericContainer("busybox:1.31.1") + public GenericContainer bboxWithMinimumDuration = new GenericContainer<>(DockerImageName.parse("busybox:1.31.1")) .withCommand("sh", "-c", String.format("sleep 5 && echo \"%s\"", HELLO_TESTCONTAINERS)) .withStartupCheckStrategy( new MinimumDurationRunningStartupCheckStrategy(Duration.ofSeconds(1)) diff --git a/docs/examples/junit4/redis/src/test/java/quickstart/RedisBackedCacheIntTest.java b/docs/examples/junit4/redis/src/test/java/quickstart/RedisBackedCacheIntTest.java index f2ef1ab0220..cbb49b5fdb3 100644 --- a/docs/examples/junit4/redis/src/test/java/quickstart/RedisBackedCacheIntTest.java +++ b/docs/examples/junit4/redis/src/test/java/quickstart/RedisBackedCacheIntTest.java @@ -5,6 +5,7 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import static org.junit.Assert.assertEquals; @@ -14,7 +15,7 @@ public class RedisBackedCacheIntTest { // rule { @Rule - public GenericContainer redis = new GenericContainer<>("redis:5.0.3-alpine") + public GenericContainer redis = new GenericContainer(DockerImageName.parse("redis:5.0.3-alpine")) .withExposedPorts(6379); // } diff --git a/docs/examples/junit5/redis/src/test/java/quickstart/RedisBackedCacheIntTest.java b/docs/examples/junit5/redis/src/test/java/quickstart/RedisBackedCacheIntTest.java index 0f4f98fb669..9a3855ba23c 100644 --- a/docs/examples/junit5/redis/src/test/java/quickstart/RedisBackedCacheIntTest.java +++ b/docs/examples/junit5/redis/src/test/java/quickstart/RedisBackedCacheIntTest.java @@ -6,6 +6,7 @@ import org.testcontainers.containers.GenericContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -17,7 +18,7 @@ public class RedisBackedCacheIntTest { // container { @Container - public GenericContainer redis = new GenericContainer<>("redis:5.0.3-alpine") + public GenericContainer redis = new GenericContainer(DockerImageName.parse("redis:5.0.3-alpine")) .withExposedPorts(6379); // } diff --git a/docs/features/creating_container.md b/docs/features/creating_container.md index e92f20e71cd..443e04f1a91 100644 --- a/docs/features/creating_container.md +++ b/docs/features/creating_container.md @@ -12,9 +12,23 @@ images as temporary test dependencies. For example, if you might use it to test With a generic container, you set the container image using a parameter to the rule constructor, e.g.: ```java -new GenericContainer("jboss/wildfly:9.0.1.Final") +new GenericContainer(DockerImageName.parse("jboss/wildfly:9.0.1.Final")) ``` +### Specifying an image + +Many Container classes in Testcontainers have historically supported: + +* a no-args constructor - for example `new GenericContainer()` and `new ElasticsearchContainer()`. With these constructors, Testcontainers has traditionally used a default image name (including a fixed image tag/version). This has caused a conflict between the need to keep the defaults sane (i.e. up to date) and the need to avoid silently upgrading these dependencies along with new versions of Testcontainers. +* a single string-argument constructor, which has taken either a version or an image name as a String. This has caused some ambiguity and confusion. + +Since v1.15.0, both of these constructor types have been deprecated, for the reasons given above. + +Instead, it is highly recommended that _all containers_ be constructed using a constructor that accepts a `DockerImageName` object. +The `DockerImageName` class is an unambiguous reference to a docker image. + +It is suggested that developers treat `DockerImageName`s as you would any other potentially-constant value - consider defining a constant in your test codebase that matches the production version of the dependency you are using. + ### Examples A generic container rule can be used with any public docker image; for example: diff --git a/examples/disque-job-queue/src/test/java/DisqueBackedMailSenderTest.java b/examples/disque-job-queue/src/test/java/DisqueBackedMailSenderTest.java index 5c78b3fdbd0..add59fd15ba 100644 --- a/examples/disque-job-queue/src/test/java/DisqueBackedMailSenderTest.java +++ b/examples/disque-job-queue/src/test/java/DisqueBackedMailSenderTest.java @@ -4,10 +4,17 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.*; -import static org.rnorth.visibleassertions.VisibleAssertions.*; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.rnorth.visibleassertions.VisibleAssertions.context; +import static org.rnorth.visibleassertions.VisibleAssertions.info; /** * Created by rnorth on 03/01/2016. @@ -15,7 +22,7 @@ public class DisqueBackedMailSenderTest { @Rule - public GenericContainer container = new GenericContainer("richnorth/disque:1.0-rc1") + public GenericContainer container = new GenericContainer<>(DockerImageName.parse("richnorth/disque:1.0-rc1")) .withExposedPorts(7711); private DisqueClient disqueClient; diff --git a/examples/disque-job-queue/src/test/java/SingleDisqueInstanceTest.java b/examples/disque-job-queue/src/test/java/SingleDisqueInstanceTest.java index 8137f8fae90..3fa115bea20 100644 --- a/examples/disque-job-queue/src/test/java/SingleDisqueInstanceTest.java +++ b/examples/disque-job-queue/src/test/java/SingleDisqueInstanceTest.java @@ -7,10 +7,14 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import java.util.concurrent.TimeUnit; -import static org.rnorth.visibleassertions.VisibleAssertions.*; +import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.rnorth.visibleassertions.VisibleAssertions.assertNotNull; +import static org.rnorth.visibleassertions.VisibleAssertions.context; +import static org.rnorth.visibleassertions.VisibleAssertions.info; /** * Created by rnorth on 03/01/2016. @@ -18,7 +22,7 @@ public class SingleDisqueInstanceTest { @Rule - public GenericContainer container = new GenericContainer("richnorth/disque:1.0-rc1") + public GenericContainer container = new GenericContainer<>(DockerImageName.parse("richnorth/disque:1.0-rc1")) .withExposedPorts(7711); private DisqueCommands connection; private AddJobArgs retryAfter1Second; diff --git a/examples/gradle/wrapper/gradle-wrapper.jar b/examples/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000000..62d4c053550 Binary files /dev/null and b/examples/gradle/wrapper/gradle-wrapper.jar differ diff --git a/examples/gradle/wrapper/gradle-wrapper.properties b/examples/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..622ab64a3cb --- /dev/null +++ b/examples/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/examples/gradlew b/examples/gradlew index 56f7b0fc7bf..fbd7c515832 100755 --- a/examples/gradlew +++ b/examples/gradlew @@ -80,7 +80,8 @@ case "`uname`" in ;; esac -CLASSPATH=$APP_HOME/../gradle/wrapper/gradle-wrapper.jar +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then @@ -129,6 +130,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath @@ -154,19 +156,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -175,14 +177,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - exec "$JAVACMD" "$@" diff --git a/examples/gradlew.bat b/examples/gradlew.bat index f3a074d99d4..5093609d512 100644 --- a/examples/gradlew.bat +++ b/examples/gradlew.bat @@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @@ -79,7 +82,8 @@ set CMD_LINE_ARGS=%* :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\..\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% diff --git a/examples/linked-container/src/test/java/com/example/linkedcontainer/LinkedContainerTestImages.java b/examples/linked-container/src/test/java/com/example/linkedcontainer/LinkedContainerTestImages.java new file mode 100644 index 00000000000..8bbbafd189f --- /dev/null +++ b/examples/linked-container/src/test/java/com/example/linkedcontainer/LinkedContainerTestImages.java @@ -0,0 +1,8 @@ +package com.example.linkedcontainer; + +import org.testcontainers.utility.DockerImageName; + +public interface LinkedContainerTestImages { + DockerImageName POSTGRES_TEST_IMAGE = DockerImageName.parse("postgres:9.6.12"); + DockerImageName REDMINE_TEST_IMAGE = DockerImageName.parse("redmine:3.3.2"); +} diff --git a/examples/linked-container/src/test/java/com/example/linkedcontainer/RedmineClientTest.java b/examples/linked-container/src/test/java/com/example/linkedcontainer/RedmineClientTest.java index 82275dcc71c..b84b2a9e2c9 100644 --- a/examples/linked-container/src/test/java/com/example/linkedcontainer/RedmineClientTest.java +++ b/examples/linked-container/src/test/java/com/example/linkedcontainer/RedmineClientTest.java @@ -15,11 +15,11 @@ public class RedmineClientTest { private static final String POSTGRES_USERNAME = "redmine"; private static final String POSTGRES_PASSWORD = "secret"; - private PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer("postgres:9.6.2") + private PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer<>(LinkedContainerTestImages.POSTGRES_TEST_IMAGE) .withUsername(POSTGRES_USERNAME) .withPassword(POSTGRES_PASSWORD); - private RedmineContainer redmineContainer = new RedmineContainer("redmine:3.3.2") + private RedmineContainer redmineContainer = new RedmineContainer(LinkedContainerTestImages.REDMINE_TEST_IMAGE) .withLinkToContainer(postgreSQLContainer, "postgres") .withEnv("POSTGRES_ENV_POSTGRES_USER", POSTGRES_USERNAME) .withEnv("POSTGRES_ENV_POSTGRES_PASSWORD", POSTGRES_PASSWORD); diff --git a/examples/linked-container/src/test/java/com/example/linkedcontainer/RedmineContainer.java b/examples/linked-container/src/test/java/com/example/linkedcontainer/RedmineContainer.java index 113d0a76ec0..a75867205ab 100644 --- a/examples/linked-container/src/test/java/com/example/linkedcontainer/RedmineContainer.java +++ b/examples/linked-container/src/test/java/com/example/linkedcontainer/RedmineContainer.java @@ -3,6 +3,7 @@ import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.traits.LinkableContainer; import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; /** * A Redmine container. @@ -11,7 +12,7 @@ public class RedmineContainer extends GenericContainer { private static final int REDMINE_PORT = 3000; - public RedmineContainer(String dockerImageName) { + public RedmineContainer(DockerImageName dockerImageName) { super(dockerImageName); } diff --git a/examples/mongodb-container/src/test/java/org/testcontainers/containers/MongoDbContainer.java b/examples/mongodb-container/src/test/java/org/testcontainers/containers/MongoDbContainer.java index 00fd9c05b52..e44f2bb982e 100644 --- a/examples/mongodb-container/src/test/java/org/testcontainers/containers/MongoDbContainer.java +++ b/examples/mongodb-container/src/test/java/org/testcontainers/containers/MongoDbContainer.java @@ -1,6 +1,7 @@ package org.testcontainers.containers; import org.jetbrains.annotations.NotNull; +import org.testcontainers.utility.DockerImageName; /** @@ -24,7 +25,9 @@ public class MongoDbContainer extends GenericContainer { /** * Creates a new {@link MongoDbContainer} with the {@value DEFAULT_IMAGE_AND_TAG} image. + * @deprecated use {@link MongoDbContainer(DockerImageName)} instead */ + @Deprecated public MongoDbContainer() { this(DEFAULT_IMAGE_AND_TAG); } @@ -33,9 +36,18 @@ public MongoDbContainer() { * Creates a new {@link MongoDbContainer} with the given {@code 'image'}. * * @param image the image (e.g. {@value DEFAULT_IMAGE_AND_TAG}) to use + * @deprecated use {@link MongoDbContainer(DockerImageName)} instead */ + @Deprecated public MongoDbContainer(@NotNull String image) { - super(image); + this(DockerImageName.parse(image)); + } + + /** + * Creates a new {@link MongoDbContainer} with the specified image. + */ + public MongoDbContainer(final DockerImageName dockerImageName) { + super(dockerImageName); addExposedPort(MONGODB_PORT); } diff --git a/examples/mongodb-container/src/test/java/org/testcontainers/containers/MongoDbContainerTest.java b/examples/mongodb-container/src/test/java/org/testcontainers/containers/MongoDbContainerTest.java index 96096d51c1a..7c87e46bccd 100644 --- a/examples/mongodb-container/src/test/java/org/testcontainers/containers/MongoDbContainerTest.java +++ b/examples/mongodb-container/src/test/java/org/testcontainers/containers/MongoDbContainerTest.java @@ -1,16 +1,17 @@ package org.testcontainers.containers; +import org.junit.Test; +import org.testcontainers.utility.DockerImageName; + import java.io.IOException; import java.net.Socket; -import org.junit.Test; - public class MongoDbContainerTest { @Test public void containerStartsAndPublicPortIsAvailable() { - try (MongoDbContainer container = new MongoDbContainer()) { + try (MongoDbContainer container = new MongoDbContainer(DockerImageName.parse("mongo:4.0"))) { container.start(); assertThatPortIsAvailable(container); } diff --git a/examples/redis-backed-cache-testng/src/test/java/RedisBackedCacheTest.java b/examples/redis-backed-cache-testng/src/test/java/RedisBackedCacheTest.java index ad2d62a2f04..5d204cf99c4 100644 --- a/examples/redis-backed-cache-testng/src/test/java/RedisBackedCacheTest.java +++ b/examples/redis-backed-cache-testng/src/test/java/RedisBackedCacheTest.java @@ -1,6 +1,7 @@ import com.mycompany.cache.Cache; import com.mycompany.cache.RedisBackedCache; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; @@ -9,14 +10,16 @@ import java.util.Optional; -import static org.rnorth.visibleassertions.VisibleAssertions.*; +import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.rnorth.visibleassertions.VisibleAssertions.assertFalse; +import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; /** * Integration test for Redis-backed cache implementation. */ public class RedisBackedCacheTest { - private static GenericContainer redis = new GenericContainer("redis:3.0.6").withExposedPorts(6379); + private static GenericContainer redis = new GenericContainer<>(DockerImageName.parse("redis:3.0.6")).withExposedPorts(6379); private Cache cache; diff --git a/examples/redis-backed-cache/src/test/java/RedisBackedCacheTest.java b/examples/redis-backed-cache/src/test/java/RedisBackedCacheTest.java index eaff293e518..d9d93b8255e 100644 --- a/examples/redis-backed-cache/src/test/java/RedisBackedCacheTest.java +++ b/examples/redis-backed-cache/src/test/java/RedisBackedCacheTest.java @@ -4,11 +4,14 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import redis.clients.jedis.Jedis; import java.util.Optional; -import static org.rnorth.visibleassertions.VisibleAssertions.*; +import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.rnorth.visibleassertions.VisibleAssertions.assertFalse; +import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; /** * Integration test for Redis-backed cache implementation. @@ -16,7 +19,7 @@ public class RedisBackedCacheTest { @Rule - public GenericContainer redis = new GenericContainer("redis:3.0.6") + public GenericContainer redis = new GenericContainer<>(DockerImageName.parse("redis:3.0.6")) .withExposedPorts(6379); private Cache cache; diff --git a/examples/singleton-container/src/test/java/com/example/AbstractIntegrationTest.java b/examples/singleton-container/src/test/java/com/example/AbstractIntegrationTest.java index d779adc5630..d152540fb1c 100644 --- a/examples/singleton-container/src/test/java/com/example/AbstractIntegrationTest.java +++ b/examples/singleton-container/src/test/java/com/example/AbstractIntegrationTest.java @@ -1,10 +1,11 @@ package com.example; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; public abstract class AbstractIntegrationTest { - public static final GenericContainer redis = new GenericContainer("redis:3.0.6") + public static final GenericContainer redis = new GenericContainer<>(DockerImageName.parse("redis:3.0.6")) .withExposedPorts(6379); static { diff --git a/examples/solr-container/src/test/java/com/example/SolrQueryTest.java b/examples/solr-container/src/test/java/com/example/SolrQueryTest.java index 413d7937853..63ac67ac1cd 100644 --- a/examples/solr-container/src/test/java/com/example/SolrQueryTest.java +++ b/examples/solr-container/src/test/java/com/example/SolrQueryTest.java @@ -1,13 +1,5 @@ package com.example; -import static com.example.SolrSearchEngine.COLLECTION_NAME; -import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; - -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.Http2SolrClient; @@ -16,10 +8,21 @@ import org.junit.BeforeClass; import org.junit.Test; import org.testcontainers.containers.SolrContainer; +import org.testcontainers.utility.DockerImageName; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static com.example.SolrSearchEngine.COLLECTION_NAME; +import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; public class SolrQueryTest { - public static final SolrContainer solrContainer = new SolrContainer() + private static final DockerImageName SOLR_IMAGE = DockerImageName.parse("solr:8.3.0"); + + public static final SolrContainer solrContainer = new SolrContainer(SOLR_IMAGE) .withCollection(COLLECTION_NAME); private static SolrClient solrClient; diff --git a/examples/spring-boot/src/test/java/com/example/AbstractIntegrationTest.java b/examples/spring-boot/src/test/java/com/example/AbstractIntegrationTest.java index 79828923d7d..b6859563c69 100644 --- a/examples/spring-boot/src/test/java/com/example/AbstractIntegrationTest.java +++ b/examples/spring-boot/src/test/java/com/example/AbstractIntegrationTest.java @@ -8,6 +8,7 @@ import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = DemoApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, properties = { @@ -16,7 +17,7 @@ @ActiveProfiles("test") public abstract class AbstractIntegrationTest { - static GenericContainer redis = new GenericContainer("redis:3-alpine") + static GenericContainer redis = new GenericContainer<>(DockerImageName.parse("redis:3-alpine")) .withExposedPorts(6379); @DynamicPropertySource diff --git a/modules/cassandra/src/main/java/org/testcontainers/containers/CassandraContainer.java b/modules/cassandra/src/main/java/org/testcontainers/containers/CassandraContainer.java index 27c2f182e9e..681c58f4efb 100644 --- a/modules/cassandra/src/main/java/org/testcontainers/containers/CassandraContainer.java +++ b/modules/cassandra/src/main/java/org/testcontainers/containers/CassandraContainer.java @@ -7,6 +7,7 @@ import org.testcontainers.delegate.DatabaseDelegate; import org.testcontainers.ext.ScriptUtils; import org.testcontainers.ext.ScriptUtils.ScriptLoadException; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.MountableFile; import javax.script.ScriptException; @@ -24,7 +25,9 @@ */ public class CassandraContainer> extends GenericContainer { + @Deprecated public static final String IMAGE = "cassandra"; + public static final Integer CQL_PORT = 9042; private static final String CONTAINER_CONFIG_LOCATION = "/etc/cassandra"; private static final String USERNAME = "cassandra"; @@ -34,11 +37,23 @@ public class CassandraContainer> extends G private String initScriptPath; private boolean enableJmxReporting; + /** + * @deprecated use {@link #CassandraContainer(DockerImageName)} instead + */ + @Deprecated public CassandraContainer() { - this(IMAGE + ":3.11.2"); + this("cassandra:3.11.2"); } + /** + * @deprecated use {@link #CassandraContainer(DockerImageName)} instead + */ + @Deprecated public CassandraContainer(String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public CassandraContainer(DockerImageName dockerImageName) { super(dockerImageName); addExposedPort(CQL_PORT); setStartupAttempts(3); diff --git a/modules/cassandra/src/test/java/org/testcontainers/containers/CassandraContainerTest.java b/modules/cassandra/src/test/java/org/testcontainers/containers/CassandraContainerTest.java index 5bc68aa9972..76c8c8438d7 100644 --- a/modules/cassandra/src/test/java/org/testcontainers/containers/CassandraContainerTest.java +++ b/modules/cassandra/src/test/java/org/testcontainers/containers/CassandraContainerTest.java @@ -7,8 +7,11 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.testcontainers.containers.wait.CassandraQueryWaitStrategy; +import org.testcontainers.utility.DockerImageName; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; /** * @author Eugeny Karpov @@ -16,11 +19,13 @@ @Slf4j public class CassandraContainerTest { + private static final DockerImageName CASSANDRA_IMAGE = DockerImageName.parse("cassandra:3.11.2"); + private static final String TEST_CLUSTER_NAME_IN_CONF = "Test Cluster Integration Test"; @Test public void testSimple() { - try (CassandraContainer cassandraContainer = new CassandraContainer<>()) { + try (CassandraContainer cassandraContainer = new CassandraContainer<>(CASSANDRA_IMAGE)) { cassandraContainer.start(); ResultSet resultSet = performQuery(cassandraContainer, "SELECT release_version FROM system.local"); assertTrue("Query was not applied", resultSet.wasApplied()); @@ -31,7 +36,7 @@ public void testSimple() { @Test public void testSpecificVersion() { String cassandraVersion = "3.0.15"; - try (CassandraContainer cassandraContainer = new CassandraContainer<>("cassandra:" + cassandraVersion)) { + try (CassandraContainer cassandraContainer = new CassandraContainer<>(CASSANDRA_IMAGE.withTag(cassandraVersion))) { cassandraContainer.start(); ResultSet resultSet = performQuery(cassandraContainer, "SELECT release_version FROM system.local"); assertTrue("Query was not applied", resultSet.wasApplied()); @@ -42,7 +47,7 @@ public void testSpecificVersion() { @Test public void testConfigurationOverride() { try ( - CassandraContainer cassandraContainer = new CassandraContainer<>() + CassandraContainer cassandraContainer = new CassandraContainer<>(CASSANDRA_IMAGE) .withConfigurationOverride("cassandra-test-configuration-example") ) { cassandraContainer.start(); @@ -55,7 +60,7 @@ public void testConfigurationOverride() { @Test(expected = ContainerLaunchException.class) public void testEmptyConfigurationOverride() { try ( - CassandraContainer cassandraContainer = new CassandraContainer<>() + CassandraContainer cassandraContainer = new CassandraContainer<>(CASSANDRA_IMAGE) .withConfigurationOverride("cassandra-empty-configuration") ) { cassandraContainer.start(); @@ -65,7 +70,7 @@ public void testEmptyConfigurationOverride() { @Test public void testInitScript() { try ( - CassandraContainer cassandraContainer = new CassandraContainer<>() + CassandraContainer cassandraContainer = new CassandraContainer<>(CASSANDRA_IMAGE) .withInitScript("initial.cql") ) { cassandraContainer.start(); @@ -76,7 +81,7 @@ public void testInitScript() { @Test public void testInitScriptWithLegacyCassandra() { try ( - CassandraContainer cassandraContainer = new CassandraContainer<>("cassandra:2.2.11") + CassandraContainer cassandraContainer = new CassandraContainer<>(DockerImageName.parse("cassandra:2.2.11")) .withInitScript("initial.cql") ) { cassandraContainer.start(); @@ -84,10 +89,11 @@ public void testInitScriptWithLegacyCassandra() { } } + @SuppressWarnings("deprecation") // Using deprecated constructor for verification of backwards compatibility @Test public void testCassandraQueryWaitStrategy() { try ( - CassandraContainer cassandraContainer = new CassandraContainer<>() + CassandraContainer cassandraContainer = new CassandraContainer<>() .waitingFor(new CassandraQueryWaitStrategy()) ) { cassandraContainer.start(); @@ -96,9 +102,10 @@ public void testCassandraQueryWaitStrategy() { } } + @SuppressWarnings("deprecation") // Using deprecated constructor for verification of backwards compatibility @Test public void testCassandraGetCluster() { - try (CassandraContainer cassandraContainer = new CassandraContainer<>()) { + try (CassandraContainer cassandraContainer = new CassandraContainer<>()) { cassandraContainer.start(); ResultSet resultSet = performQuery(cassandraContainer.getCluster(), "SELECT release_version FROM system.local"); assertTrue("Query was not applied", resultSet.wasApplied()); @@ -106,7 +113,7 @@ public void testCassandraGetCluster() { } } - private void testInitScript(CassandraContainer cassandraContainer) { + private void testInitScript(CassandraContainer cassandraContainer) { ResultSet resultSet = performQuery(cassandraContainer, "SELECT * FROM keySpaceTest.catalog_category"); assertTrue("Query was not applied", resultSet.wasApplied()); Row row = resultSet.one(); @@ -114,7 +121,7 @@ private void testInitScript(CassandraContainer cassandraContainer) { assertEquals("Inserted row is not in expected state", "test_category", row.getString(1)); } - private ResultSet performQuery(CassandraContainer cassandraContainer, String cql) { + private ResultSet performQuery(CassandraContainer cassandraContainer, String cql) { Cluster explicitCluster = Cluster.builder() .addContactPoint(cassandraContainer.getHost()) .withPort(cassandraContainer.getMappedPort(CassandraContainer.CQL_PORT)) diff --git a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainer.java b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainer.java index dd48f32bece..6bdcff7b3f2 100644 --- a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainer.java +++ b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseContainer.java @@ -1,12 +1,14 @@ package org.testcontainers.containers; import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; +import org.testcontainers.utility.DockerImageName; import java.time.Duration; public class ClickHouseContainer extends JdbcDatabaseContainer { public static final String NAME = "clickhouse"; public static final String IMAGE = "yandex/clickhouse-server"; + @Deprecated public static final String DEFAULT_TAG = "18.10.3"; public static final Integer HTTP_PORT = 8123; @@ -20,11 +22,23 @@ public class ClickHouseContainer extends JdbcDatabaseContainer { private String username = "default"; private String password = ""; + /** + * @deprecated use {@link ClickHouseContainer(DockerImageName)} instead + */ + @Deprecated public ClickHouseContainer() { super(IMAGE + ":" + DEFAULT_TAG); } + /** + * @deprecated use {@link ClickHouseContainer(DockerImageName)} instead + */ + @Deprecated public ClickHouseContainer(String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public ClickHouseContainer(final DockerImageName dockerImageName) { super(dockerImageName); withExposedPorts(HTTP_PORT, NATIVE_PORT); diff --git a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseProvider.java b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseProvider.java index be5a01657f0..cd2453b8349 100644 --- a/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseProvider.java +++ b/modules/clickhouse/src/main/java/org/testcontainers/containers/ClickHouseProvider.java @@ -1,5 +1,7 @@ package org.testcontainers.containers; +import org.testcontainers.utility.DockerImageName; + public class ClickHouseProvider extends JdbcDatabaseContainerProvider { @Override public boolean supports(String databaseType) { @@ -8,6 +10,6 @@ public boolean supports(String databaseType) { @Override public JdbcDatabaseContainer newInstance(String tag) { - return new ClickHouseContainer(ClickHouseContainer.IMAGE + ":" + tag); + return new ClickHouseContainer(DockerImageName.parse(ClickHouseContainer.IMAGE).withTag(tag)); } } diff --git a/modules/clickhouse/src/test/java/org/testcontainers/ClickhouseTestImages.java b/modules/clickhouse/src/test/java/org/testcontainers/ClickhouseTestImages.java new file mode 100644 index 00000000000..961df045bd1 --- /dev/null +++ b/modules/clickhouse/src/test/java/org/testcontainers/ClickhouseTestImages.java @@ -0,0 +1,7 @@ +package org.testcontainers; + +import org.testcontainers.utility.DockerImageName; + +public interface ClickhouseTestImages { + DockerImageName CLICKHOUSE_IMAGE = DockerImageName.parse("yandex/clickhouse-server:18.10.3"); +} diff --git a/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseTest.java b/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseTest.java index 2dbce0b3593..8f3879673a0 100644 --- a/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseTest.java +++ b/modules/clickhouse/src/test/java/org/testcontainers/junit/clickhouse/SimpleClickhouseTest.java @@ -8,12 +8,13 @@ import java.sql.SQLException; import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.testcontainers.ClickhouseTestImages.CLICKHOUSE_IMAGE; public class SimpleClickhouseTest extends AbstractContainerDatabaseTest { @Test public void testSimple() throws SQLException { - try (ClickHouseContainer clickhouse = new ClickHouseContainer()) { + try (ClickHouseContainer clickhouse = new ClickHouseContainer(CLICKHOUSE_IMAGE)) { clickhouse.start(); ResultSet resultSet = performQuery(clickhouse, "SELECT 1"); diff --git a/modules/cockroachdb/src/main/java/org/testcontainers/containers/CockroachContainer.java b/modules/cockroachdb/src/main/java/org/testcontainers/containers/CockroachContainer.java index de64902c88a..54420155f05 100644 --- a/modules/cockroachdb/src/main/java/org/testcontainers/containers/CockroachContainer.java +++ b/modules/cockroachdb/src/main/java/org/testcontainers/containers/CockroachContainer.java @@ -1,6 +1,7 @@ package org.testcontainers.containers; import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; +import org.testcontainers.utility.DockerImageName; import java.time.Duration; @@ -18,11 +19,23 @@ public class CockroachContainer extends JdbcDatabaseContainer { /** * Creates a new couchbase container with the default image and version. + * @deprecated use {@link CouchbaseContainer(DockerImageName)} instead */ + @Deprecated public CouchbaseContainer() { this(DOCKER_IMAGE_NAME + ":" + VERSION); } @@ -95,10 +98,20 @@ public CouchbaseContainer() { /** * Creates a new couchbase container with a custom image name. * - * @param imageName the image name that should be used. + * @param dockerImageName the image name that should be used. + * @deprecated use {@link CouchbaseContainer(DockerImageName)} instead */ - public CouchbaseContainer(final String imageName) { - super(imageName); + @Deprecated + public CouchbaseContainer(final String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + /** + * Create a new couchbase container with the specified image name. + * @param dockerImageName + */ + public CouchbaseContainer(final DockerImageName dockerImageName) { + super(dockerImageName); } /** diff --git a/modules/couchbase/src/test/java/org/testcontainers/couchbase/CouchbaseContainerTest.java b/modules/couchbase/src/test/java/org/testcontainers/couchbase/CouchbaseContainerTest.java index c5c9f18a58b..3a4438c1fc6 100644 --- a/modules/couchbase/src/test/java/org/testcontainers/couchbase/CouchbaseContainerTest.java +++ b/modules/couchbase/src/test/java/org/testcontainers/couchbase/CouchbaseContainerTest.java @@ -24,12 +24,15 @@ import com.couchbase.client.java.env.CouchbaseEnvironment; import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; import org.junit.Test; +import org.testcontainers.utility.DockerImageName; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; public class CouchbaseContainerTest { + private static final DockerImageName COUCHBASE_IMAGE = DockerImageName.parse("couchbase/server:6.5.1"); + @Test public void testBasicContainerUsage() { // bucket_definition { @@ -38,7 +41,7 @@ public void testBasicContainerUsage() { try ( // container_definition { - CouchbaseContainer container = new CouchbaseContainer() + CouchbaseContainer container = new CouchbaseContainer(COUCHBASE_IMAGE) .withBucket(bucketDefinition) // } ) { diff --git a/modules/db2/src/main/java/org/testcontainers/containers/Db2Container.java b/modules/db2/src/main/java/org/testcontainers/containers/Db2Container.java index 05edcb2c3ed..aa6d136aaec 100644 --- a/modules/db2/src/main/java/org/testcontainers/containers/Db2Container.java +++ b/modules/db2/src/main/java/org/testcontainers/containers/Db2Container.java @@ -1,6 +1,7 @@ package org.testcontainers.containers; import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.LicenseAcceptance; import java.time.Duration; @@ -19,12 +20,24 @@ public class Db2Container extends JdbcDatabaseContainer { private String username = "db2inst1"; private String password = "foobar1234"; + /** + * @deprecated use {@link Db2Container(DockerImageName)} instead + */ + @Deprecated public Db2Container() { this(DEFAULT_DB2_IMAGE_NAME + ":" + DEFAULT_TAG); } - public Db2Container(String imageName) { - super(imageName); + /** + * @deprecated use {@link Db2Container(DockerImageName)} instead + */ + @Deprecated + public Db2Container(String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public Db2Container(final DockerImageName dockerImageName) { + super(dockerImageName); withPrivilegedMode(true); this.waitStrategy = new LogMessageWaitStrategy() .withRegEx(".*Setup has completed\\..*") diff --git a/modules/db2/src/main/java/org/testcontainers/containers/Db2ContainerProvider.java b/modules/db2/src/main/java/org/testcontainers/containers/Db2ContainerProvider.java index 5c78fdc0505..618b97c3ca6 100644 --- a/modules/db2/src/main/java/org/testcontainers/containers/Db2ContainerProvider.java +++ b/modules/db2/src/main/java/org/testcontainers/containers/Db2ContainerProvider.java @@ -1,5 +1,7 @@ package org.testcontainers.containers; +import org.testcontainers.utility.DockerImageName; + public class Db2ContainerProvider extends JdbcDatabaseContainerProvider { @Override public boolean supports(String databaseType) { @@ -13,6 +15,6 @@ public JdbcDatabaseContainer newInstance() { @Override public JdbcDatabaseContainer newInstance(String tag) { - return new Db2Container(Db2Container.DEFAULT_DB2_IMAGE_NAME + ":" + tag); + return new Db2Container(DockerImageName.parse(Db2Container.DEFAULT_DB2_IMAGE_NAME).withTag(tag)); } } diff --git a/modules/db2/src/test/java/org/testcontainers/Db2TestImages.java b/modules/db2/src/test/java/org/testcontainers/Db2TestImages.java new file mode 100644 index 00000000000..b0bfc869272 --- /dev/null +++ b/modules/db2/src/test/java/org/testcontainers/Db2TestImages.java @@ -0,0 +1,7 @@ +package org.testcontainers; + +import org.testcontainers.utility.DockerImageName; + +public interface Db2TestImages { + DockerImageName DB2_IMAGE = DockerImageName.parse("ibmcom/db2:11.5.0.0a"); +} diff --git a/modules/db2/src/test/java/org/testcontainers/junit/db2/SimpleDb2Test.java b/modules/db2/src/test/java/org/testcontainers/junit/db2/SimpleDb2Test.java index 6cc7535f785..b7a1d5478e8 100644 --- a/modules/db2/src/test/java/org/testcontainers/junit/db2/SimpleDb2Test.java +++ b/modules/db2/src/test/java/org/testcontainers/junit/db2/SimpleDb2Test.java @@ -10,12 +10,13 @@ import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertThat; import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.testcontainers.Db2TestImages.DB2_IMAGE; public class SimpleDb2Test extends AbstractContainerDatabaseTest { @Test public void testSimple() throws SQLException { - try (Db2Container db2 = new Db2Container() + try (Db2Container db2 = new Db2Container(DB2_IMAGE) .acceptLicense()) { db2.start(); @@ -29,7 +30,7 @@ public void testSimple() throws SQLException { @Test public void testWithAdditionalUrlParamInJdbcUrl() { - try (Db2Container db2 = new Db2Container() + try (Db2Container db2 = new Db2Container(DB2_IMAGE) .withUrlParam("sslConnection", "false") .acceptLicense()) { diff --git a/modules/dynalite/src/main/java/org/testcontainers/dynamodb/DynaliteContainer.java b/modules/dynalite/src/main/java/org/testcontainers/dynamodb/DynaliteContainer.java index 6280ddb9421..6063c1a5dbe 100644 --- a/modules/dynalite/src/main/java/org/testcontainers/dynamodb/DynaliteContainer.java +++ b/modules/dynalite/src/main/java/org/testcontainers/dynamodb/DynaliteContainer.java @@ -7,6 +7,7 @@ import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; /** * Container for Dynalite, a DynamoDB clone. @@ -16,15 +17,28 @@ public class DynaliteContainer extends GenericContainer { private static final String IMAGE_NAME = "quay.io/testcontainers/dynalite:v1.2.1-1"; private static final int MAPPED_PORT = 4567; + /** + * @deprecated use {@link DynaliteContainer(DockerImageName)} instead + */ + @Deprecated public DynaliteContainer() { this(IMAGE_NAME); withExposedPorts(MAPPED_PORT); } - public DynaliteContainer(String imageName) { - super(imageName); + /** + * @deprecated use {@link DynaliteContainer(DockerImageName)} instead + */ + @Deprecated + public DynaliteContainer(String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); } + public DynaliteContainer(final DockerImageName dockerImageName) { + super(dockerImageName); + } + + /** * Gets a preconfigured {@link AmazonDynamoDB} client object for connecting to this * container. diff --git a/modules/dynalite/src/test/java/org/testcontainers/dynamodb/DynaliteContainerTest.java b/modules/dynalite/src/test/java/org/testcontainers/dynamodb/DynaliteContainerTest.java index 524d3f6c34c..0b440939139 100644 --- a/modules/dynalite/src/test/java/org/testcontainers/dynamodb/DynaliteContainerTest.java +++ b/modules/dynalite/src/test/java/org/testcontainers/dynamodb/DynaliteContainerTest.java @@ -2,17 +2,26 @@ import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; -import com.amazonaws.services.dynamodbv2.model.*; +import com.amazonaws.services.dynamodbv2.model.AttributeDefinition; +import com.amazonaws.services.dynamodbv2.model.CreateTableRequest; +import com.amazonaws.services.dynamodbv2.model.KeySchemaElement; +import com.amazonaws.services.dynamodbv2.model.KeyType; +import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; +import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType; +import com.amazonaws.services.dynamodbv2.model.TableDescription; import org.junit.Rule; import org.junit.Test; +import org.testcontainers.utility.DockerImageName; import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; import static org.rnorth.visibleassertions.VisibleAssertions.assertNotNull; public class DynaliteContainerTest { + private static final DockerImageName DYNALITE_IMAGE = DockerImageName.parse("quay.io/testcontainers/dynalite:v1.2.1-1"); + @Rule - public DynaliteContainer dynamoDB = new DynaliteContainer(); + public DynaliteContainer dynamoDB = new DynaliteContainer(DYNALITE_IMAGE); @Test public void simpleTestWithManualClientCreation() { diff --git a/modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/ElasticsearchContainer.java b/modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/ElasticsearchContainer.java index e9a0b95d7ed..6ad0172269d 100644 --- a/modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/ElasticsearchContainer.java +++ b/modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/ElasticsearchContainer.java @@ -3,6 +3,7 @@ import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; import org.testcontainers.utility.Base58; +import org.testcontainers.utility.DockerImageName; import java.net.InetSocketAddress; import java.time.Duration; @@ -36,6 +37,10 @@ public class ElasticsearchContainer extends GenericContainer basic @@ -54,6 +59,7 @@ public void stopRestClient() throws IOException { } } + @SuppressWarnings("deprecation") // Using deprecated constructor for verification of backwards compatibility @Test public void elasticsearchDefaultTest() throws IOException { // Create the elasticsearch container. @@ -78,7 +84,7 @@ public void elasticsearchDefaultTest() throws IOException { @Test public void elasticsearchVersion() throws IOException { - try (ElasticsearchContainer container = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:" + ELASTICSEARCH_VERSION)) { + try (ElasticsearchContainer container = new ElasticsearchContainer(ELASTICSEARCH_IMAGE)) { container.start(); Response response = getClient(container).performRequest(new Request("GET", "/")); assertThat(response.getStatusLine().getStatusCode(), is(200)); @@ -89,10 +95,14 @@ public void elasticsearchVersion() throws IOException { @Test public void elasticsearchOssImage() throws IOException { - try ( - // oosContainer { - ElasticsearchContainer container = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch-oss:" + ELASTICSEARCH_VERSION) - // } + try (ElasticsearchContainer container = + // oosContainer { + new ElasticsearchContainer( + DockerImageName + .parse("docker.elastic.co/elasticsearch/elasticsearch-oss") + .withTag(ELASTICSEARCH_VERSION) + ) + // } ) { container.start(); Response response = getClient(container).performRequest(new Request("GET", "/")); @@ -104,6 +114,7 @@ public void elasticsearchOssImage() throws IOException { } } + @SuppressWarnings("deprecation") // Using deprecated constructor for verification of backwards compatibility @Test public void restClientClusterHealth() throws IOException { // httpClientContainer { @@ -122,10 +133,10 @@ public void restClientClusterHealth() throws IOException { .build(); Response response = client.performRequest(new Request("GET", "/_cluster/health")); - // }} + // }} assertThat(response.getStatusLine().getStatusCode(), is(200)); assertThat(EntityUtils.toString(response.getEntity()), containsString("cluster_name")); - // httpClientContainer {{ + // httpClientContainer {{ } // } } @@ -134,7 +145,11 @@ public void restClientClusterHealth() throws IOException { public void transportClientClusterHealth() { // transportClientContainer { // Create the elasticsearch container. - try (ElasticsearchContainer container = new ElasticsearchContainer()) { + try (ElasticsearchContainer container = new ElasticsearchContainer( + DockerImageName + .parse("docker.elastic.co/elasticsearch/elasticsearch") + .withTag("6.4.1") + )){ // Start the container. This step might take some time... container.start(); diff --git a/modules/influxdb/src/main/java/org/testcontainers/containers/InfluxDBContainer.java b/modules/influxdb/src/main/java/org/testcontainers/containers/InfluxDBContainer.java index 68efc516504..5d883fea9a7 100644 --- a/modules/influxdb/src/main/java/org/testcontainers/containers/InfluxDBContainer.java +++ b/modules/influxdb/src/main/java/org/testcontainers/containers/InfluxDBContainer.java @@ -4,6 +4,7 @@ import org.influxdb.InfluxDBFactory; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.containers.wait.strategy.WaitAllStrategy; +import org.testcontainers.utility.DockerImageName; import java.util.Collections; import java.util.Set; @@ -26,13 +27,24 @@ public class InfluxDBContainer> extends Gen private String username = "any"; private String password = "any"; - + /** + * @deprecated use {@link InfluxDBContainer(DockerImageName)} instead + */ + @Deprecated public InfluxDBContainer() { this(VERSION); } + /** + * @deprecated use {@link InfluxDBContainer(DockerImageName)} instead + */ + @Deprecated public InfluxDBContainer(final String version) { - super(IMAGE_NAME + ":" + version); + this(DockerImageName.parse(IMAGE_NAME + ":" + version)); + } + + public InfluxDBContainer(final DockerImageName dockerImageName) { + super(dockerImageName); waitStrategy = new WaitAllStrategy() .withStrategy(Wait.forHttp("/ping").withBasicCredentials(username, password).forStatusCode(204)) .withStrategy(Wait.forListeningPort()); diff --git a/modules/influxdb/src/test/java/org/testcontainers/containers/InfluxDBContainerTest.java b/modules/influxdb/src/test/java/org/testcontainers/containers/InfluxDBContainerTest.java index fa2e54fd0c9..7acf030b5e4 100644 --- a/modules/influxdb/src/test/java/org/testcontainers/containers/InfluxDBContainerTest.java +++ b/modules/influxdb/src/test/java/org/testcontainers/containers/InfluxDBContainerTest.java @@ -11,7 +11,7 @@ public class InfluxDBContainerTest { @ClassRule - public static InfluxDBContainer influxDBContainer = new InfluxDBContainer(); + public static InfluxDBContainer influxDBContainer = new InfluxDBContainer<>(InfluxDBTestImages.INFLUXDB_TEST_IMAGE); @Test public void getUrl() { diff --git a/modules/influxdb/src/test/java/org/testcontainers/containers/InfluxDBContainerWithUserTest.java b/modules/influxdb/src/test/java/org/testcontainers/containers/InfluxDBContainerWithUserTest.java index 81ad62a7b47..b045ca297c1 100644 --- a/modules/influxdb/src/test/java/org/testcontainers/containers/InfluxDBContainerWithUserTest.java +++ b/modules/influxdb/src/test/java/org/testcontainers/containers/InfluxDBContainerWithUserTest.java @@ -17,13 +17,13 @@ public class InfluxDBContainerWithUserTest { - private static final String TEST_VERSION = "1.4.3"; + private static final String TEST_VERSION = InfluxDBTestImages.INFLUXDB_TEST_IMAGE.getVersionPart(); private static final String DATABASE = "test"; private static final String USER = "test-user"; private static final String PASSWORD = "test-password"; @Rule - public InfluxDBContainer influxDBContainer = new InfluxDBContainer(TEST_VERSION) + public InfluxDBContainer influxDBContainer = new InfluxDBContainer<>(InfluxDBTestImages.INFLUXDB_TEST_IMAGE) .withDatabase(DATABASE) .withUsername(USER) .withPassword(PASSWORD); diff --git a/modules/influxdb/src/test/java/org/testcontainers/containers/InfluxDBTestImages.java b/modules/influxdb/src/test/java/org/testcontainers/containers/InfluxDBTestImages.java new file mode 100644 index 00000000000..a0e2d31bbdf --- /dev/null +++ b/modules/influxdb/src/test/java/org/testcontainers/containers/InfluxDBTestImages.java @@ -0,0 +1,7 @@ +package org.testcontainers.containers; + +import org.testcontainers.utility.DockerImageName; + +public interface InfluxDBTestImages { + DockerImageName INFLUXDB_TEST_IMAGE = DockerImageName.parse("influxdb:1.4.3"); +} diff --git a/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java b/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java index 62fe43e7932..4d1c4ece67b 100644 --- a/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java +++ b/modules/jdbc/src/main/java/org/testcontainers/containers/JdbcDatabaseContainer.java @@ -8,6 +8,7 @@ import org.testcontainers.delegate.DatabaseDelegate; import org.testcontainers.ext.ScriptUtils; import org.testcontainers.jdbc.JdbcDatabaseDelegate; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.MountableFile; import java.sql.Connection; @@ -38,14 +39,22 @@ public abstract class JdbcDatabaseContainer image) { super(image); } + public JdbcDatabaseContainer(final DockerImageName dockerImageName) { + super(dockerImageName); + } + /** * @return the name of the actual JDBC driver to use */ diff --git a/modules/jdbc/src/test/java/org/testcontainers/jdbc/MissingJdbcDriverTest.java b/modules/jdbc/src/test/java/org/testcontainers/jdbc/MissingJdbcDriverTest.java index 38ae38095eb..88398cebf85 100644 --- a/modules/jdbc/src/test/java/org/testcontainers/jdbc/MissingJdbcDriverTest.java +++ b/modules/jdbc/src/test/java/org/testcontainers/jdbc/MissingJdbcDriverTest.java @@ -3,6 +3,7 @@ import com.google.common.base.Throwables; import org.junit.Test; import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.utility.DockerImageName; import java.sql.Connection; import java.sql.SQLException; @@ -39,7 +40,7 @@ static class MissingDriverContainer extends JdbcDatabaseContainer { private final AtomicInteger connectionAttempts = new AtomicInteger(); MissingDriverContainer() { - super("mysql:5.7.22"); + super(DockerImageName.parse("mysql:5.7.22")); withEnv("MYSQL_ROOT_PASSWORD", "test"); withExposedPorts(3306); } diff --git a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/JUnitJupiterTestImages.java b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/JUnitJupiterTestImages.java new file mode 100644 index 00000000000..e99d1ec720c --- /dev/null +++ b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/JUnitJupiterTestImages.java @@ -0,0 +1,8 @@ +package org.testcontainers.junit.jupiter; + +import org.testcontainers.utility.DockerImageName; + +public interface JUnitJupiterTestImages { + DockerImageName POSTGRES_IMAGE = DockerImageName.parse("postgres:9.6.12"); + DockerImageName HTTPD_IMAGE = DockerImageName.parse("httpd:2.4-alpine"); +} diff --git a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/PostgresContainerTests.java b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/PostgresContainerTests.java index 765a9f6ff6b..4cbc331e64b 100644 --- a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/PostgresContainerTests.java +++ b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/PostgresContainerTests.java @@ -9,12 +9,13 @@ import java.sql.Statement; import static org.junit.Assert.assertEquals; +import static org.testcontainers.junit.jupiter.JUnitJupiterTestImages.POSTGRES_IMAGE; @Testcontainers class PostgresContainerTests { @Container - private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer() + private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer<>(POSTGRES_IMAGE) .withDatabaseName("foo") .withUsername("foo") .withPassword("secret"); diff --git a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersNestedRestartedContainerTests.java b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersNestedRestartedContainerTests.java index fb753744425..6e02e31b774 100644 --- a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersNestedRestartedContainerTests.java +++ b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersNestedRestartedContainerTests.java @@ -4,16 +4,16 @@ import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.testcontainers.junit.jupiter.JUnitJupiterTestImages.HTTPD_IMAGE; // testClass { @Testcontainers class TestcontainersNestedRestartedContainerTests { @Container - private final GenericContainer topLevelContainer = new GenericContainer("httpd:2.4-alpine") + private final GenericContainer topLevelContainer = new GenericContainer<>(HTTPD_IMAGE) .withExposedPorts(80); // }} @@ -34,7 +34,7 @@ void top_level_container_should_be_running() { class NestedTestCase { @Container - private final GenericContainer nestedContainer = new GenericContainer("httpd:2.4-alpine") + private final GenericContainer nestedContainer = new GenericContainer<>(HTTPD_IMAGE) .withExposedPorts(80); @Test diff --git a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersNestedSharedContainerTests.java b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersNestedSharedContainerTests.java index 371a5bae178..cf59e0338a2 100644 --- a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersNestedSharedContainerTests.java +++ b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersNestedSharedContainerTests.java @@ -6,12 +6,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.testcontainers.junit.jupiter.JUnitJupiterTestImages.HTTPD_IMAGE; @Testcontainers class TestcontainersNestedSharedContainerTests { @Container - private static final GenericContainer TOP_LEVEL_CONTAINER = new GenericContainer("httpd:2.4-alpine") + private static final GenericContainer TOP_LEVEL_CONTAINER = new GenericContainer<>(HTTPD_IMAGE) .withExposedPorts(80); private static String topLevelContainerId; diff --git a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersRestartBetweenTests.java b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersRestartBetweenTests.java index 2d6959ae065..eeb63b72380 100644 --- a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersRestartBetweenTests.java +++ b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersRestartBetweenTests.java @@ -4,12 +4,13 @@ import org.testcontainers.containers.GenericContainer; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.testcontainers.junit.jupiter.JUnitJupiterTestImages.HTTPD_IMAGE; @Testcontainers class TestcontainersRestartBetweenTests { @Container - private GenericContainer genericContainer = new GenericContainer("httpd:2.4-alpine") + private GenericContainer genericContainer = new GenericContainer<>(HTTPD_IMAGE) .withExposedPorts(80); private static String lastContainerId; diff --git a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersSharedContainerTests.java b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersSharedContainerTests.java index 321c0d6282f..60094994f69 100644 --- a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersSharedContainerTests.java +++ b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestcontainersSharedContainerTests.java @@ -6,12 +6,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.testcontainers.junit.jupiter.JUnitJupiterTestImages.HTTPD_IMAGE; @Testcontainers class TestcontainersSharedContainerTests { @Container - private static final GenericContainer GENERIC_CONTAINER = new GenericContainer("httpd:2.4-alpine") + private static final GenericContainer GENERIC_CONTAINER = new GenericContainer<>(HTTPD_IMAGE) .withExposedPorts(80); private static String lastContainerId; diff --git a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/inheritance/RedisContainer.java b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/inheritance/RedisContainer.java index 177a48bb9d0..0a9ec62fca2 100644 --- a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/inheritance/RedisContainer.java +++ b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/inheritance/RedisContainer.java @@ -1,16 +1,13 @@ package org.testcontainers.junit.jupiter.inheritance; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; import redis.clients.jedis.Jedis; public class RedisContainer extends GenericContainer { public RedisContainer() { - this("redis:3.2.11"); - } - - public RedisContainer(String dockerImageName) { - super(dockerImageName); + super(DockerImageName.parse("redis:3.2.11")); withExposedPorts(6379); } diff --git a/modules/kafka/src/main/java/org/testcontainers/containers/KafkaContainer.java b/modules/kafka/src/main/java/org/testcontainers/containers/KafkaContainer.java index 9746849be29..2451278b1c2 100644 --- a/modules/kafka/src/main/java/org/testcontainers/containers/KafkaContainer.java +++ b/modules/kafka/src/main/java/org/testcontainers/containers/KafkaContainer.java @@ -4,6 +4,7 @@ import com.github.dockerjava.api.command.InspectContainerResponse; import lombok.SneakyThrows; import org.testcontainers.images.builder.Transferable; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.TestcontainersConfiguration; import java.nio.charset.StandardCharsets; @@ -29,12 +30,24 @@ public class KafkaContainer extends GenericContainer { private int port = PORT_NOT_ASSIGNED; + /** + * @deprecated use {@link KafkaContainer(DockerImageName)} instead + */ + @Deprecated public KafkaContainer() { this("5.2.1"); } + /** + * @deprecated use {@link KafkaContainer(DockerImageName)} instead + */ + @Deprecated public KafkaContainer(String confluentPlatformVersion) { - super(TestcontainersConfiguration.getInstance().getKafkaImage() + ":" + confluentPlatformVersion); + this(DockerImageName.parse(TestcontainersConfiguration.getInstance().getKafkaImage() + ":" + confluentPlatformVersion)); + } + + public KafkaContainer(final DockerImageName dockerImageName) { + super(dockerImageName); withExposedPorts(KAFKA_PORT); diff --git a/modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java b/modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java index 25bc1b5022c..b8cd5c9be9c 100644 --- a/modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java +++ b/modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java @@ -13,6 +13,7 @@ import org.junit.Rule; import org.junit.Test; import org.rnorth.ducttape.unreliables.Unreliables; +import org.testcontainers.utility.DockerImageName; import java.time.Duration; import java.util.Arrays; @@ -24,6 +25,9 @@ public class KafkaContainerTest { + private static final DockerImageName KAFKA_TEST_IMAGE = DockerImageName.parse("confluentinc/cp-kafka:5.2.1"); + private static final DockerImageName ZOOKEEPER_TEST_IMAGE = DockerImageName.parse("confluentinc/cp-zookeeper:4.0.0"); + // junitRule { @Rule public KafkaContainer kafka = new KafkaContainer(); @@ -31,7 +35,7 @@ public class KafkaContainerTest { @Test public void testUsage() throws Exception { - try (KafkaContainer kafka = new KafkaContainer()) { + try (KafkaContainer kafka = new KafkaContainer(KAFKA_TEST_IMAGE)) { kafka.start(); testKafkaFunctionality(kafka.getBootstrapServers()); } @@ -42,7 +46,7 @@ public void testUsage() throws Exception { public void testUsageWithVersion() throws Exception { try ( // constructorWithVersion { - KafkaContainer kafka = new KafkaContainer("4.1.2") + KafkaContainer kafka = new KafkaContainer(KAFKA_TEST_IMAGE) // } ) { kafka.start(); @@ -60,12 +64,12 @@ public void testExternalZookeeperWithExternalNetwork() throws Exception { Network network = Network.newNetwork(); // withExternalZookeeper { - KafkaContainer kafka = new KafkaContainer() + KafkaContainer kafka = new KafkaContainer(KAFKA_TEST_IMAGE) .withNetwork(network) .withExternalZookeeper("zookeeper:2181"); // } - GenericContainer zookeeper = new GenericContainer("confluentinc/cp-zookeeper:4.0.0") + GenericContainer zookeeper = new GenericContainer<>(ZOOKEEPER_TEST_IMAGE) .withNetwork(network) .withNetworkAliases("zookeeper") .withEnv("ZOOKEEPER_CLIENT_PORT", "2181"); diff --git a/modules/localstack/src/main/java/org/testcontainers/containers/localstack/LocalStackContainer.java b/modules/localstack/src/main/java/org/testcontainers/containers/localstack/LocalStackContainer.java index 72eb320c729..0136d94e3b2 100644 --- a/modules/localstack/src/main/java/org/testcontainers/containers/localstack/LocalStackContainer.java +++ b/modules/localstack/src/main/java/org/testcontainers/containers/localstack/LocalStackContainer.java @@ -10,6 +10,7 @@ import org.rnorth.ducttape.Preconditions; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.TestcontainersConfiguration; import java.net.InetAddress; @@ -36,12 +37,24 @@ public class LocalStackContainer extends GenericContainer { private final List services = new ArrayList<>(); + /** + * @deprecated use {@link LocalStackContainer(DockerImageName)} instead + */ + @Deprecated public LocalStackContainer() { this(VERSION); } + /** + * @deprecated use {@link LocalStackContainer(DockerImageName)} instead + */ + @Deprecated public LocalStackContainer(String version) { - super(TestcontainersConfiguration.getInstance().getLocalStackImage() + ":" + version); + this(DockerImageName.parse(TestcontainersConfiguration.getInstance().getLocalStackImage() + ":" + version)); + } + + public LocalStackContainer(final DockerImageName dockerImageName) { + super(dockerImageName); withFileSystemBind("//var/run/docker.sock", "/var/run/docker.sock"); waitingFor(Wait.forLogMessage(".*Ready\\.\n", 1)); diff --git a/modules/localstack/src/test/java/org/testcontainers/containers/localstack/LocalstackContainerTest.java b/modules/localstack/src/test/java/org/testcontainers/containers/localstack/LocalstackContainerTest.java index d4e2f0c2864..63be9d66df7 100644 --- a/modules/localstack/src/test/java/org/testcontainers/containers/localstack/LocalstackContainerTest.java +++ b/modules/localstack/src/test/java/org/testcontainers/containers/localstack/LocalstackContainerTest.java @@ -29,6 +29,7 @@ import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; +import org.testcontainers.utility.DockerImageName; import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; import software.amazon.awssdk.regions.Region; @@ -43,7 +44,10 @@ import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; import static org.rnorth.visibleassertions.VisibleAssertions.assertThat; import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; -import static org.testcontainers.containers.localstack.LocalStackContainer.Service.*; +import static org.testcontainers.containers.localstack.LocalStackContainer.Service.CLOUDWATCHLOGS; +import static org.testcontainers.containers.localstack.LocalStackContainer.Service.KMS; +import static org.testcontainers.containers.localstack.LocalStackContainer.Service.S3; +import static org.testcontainers.containers.localstack.LocalStackContainer.Service.SQS; /** * Tests for Localstack Container, used both in bridge network (exposed to host) and docker network modes. @@ -56,11 +60,14 @@ @RunWith(Enclosed.class) public class LocalstackContainerTest { + private static final DockerImageName LOCALSTACK_IMAGE = DockerImageName.parse("localstack/localstack:0.10.8"); + private static final DockerImageName AWS_CLI_IMAGE = DockerImageName.parse("atlassian/pipelines-awscli:1.16.302"); + public static class WithoutNetwork { // without_network { @ClassRule - public static LocalStackContainer localstack = new LocalStackContainer() + public static LocalStackContainer localstack = new LocalStackContainer(LOCALSTACK_IMAGE) .withServices(S3, SQS, CLOUDWATCHLOGS, KMS); // } @@ -160,14 +167,14 @@ public static class WithNetwork { private static Network network = Network.newNetwork(); @ClassRule - public static LocalStackContainer localstackInDockerNetwork = new LocalStackContainer() + public static LocalStackContainer localstackInDockerNetwork = new LocalStackContainer(LOCALSTACK_IMAGE) .withNetwork(network) .withNetworkAliases("notthis", "localstack") // the last alias is used for HOSTNAME_EXTERNAL .withServices(S3, SQS, CLOUDWATCHLOGS); // } @ClassRule - public static GenericContainer awsCliInDockerNetwork = new GenericContainer<>("atlassian/pipelines-awscli") + public static GenericContainer awsCliInDockerNetwork = new GenericContainer<>(AWS_CLI_IMAGE) .withNetwork(network) .withCreateContainerCmdModifier(cmd -> cmd.withEntrypoint("top")) .withEnv("AWS_ACCESS_KEY_ID", "accesskey") diff --git a/modules/mariadb/src/main/java/org/testcontainers/containers/MariaDBContainer.java b/modules/mariadb/src/main/java/org/testcontainers/containers/MariaDBContainer.java index 04d745a9efe..e137c186209 100644 --- a/modules/mariadb/src/main/java/org/testcontainers/containers/MariaDBContainer.java +++ b/modules/mariadb/src/main/java/org/testcontainers/containers/MariaDBContainer.java @@ -1,5 +1,7 @@ package org.testcontainers.containers; +import org.testcontainers.utility.DockerImageName; + /** * Container implementation for the MariaDB project. * @@ -22,11 +24,23 @@ public class MariaDBContainer> extends JdbcD private static final String MARIADB_ROOT_USER = "root"; private static final String MY_CNF_CONFIG_OVERRIDE_PARAM_NAME = "TC_MY_CNF"; + /** + * @deprecated use {@link MariaDBContainer(DockerImageName)} instead + */ + @Deprecated public MariaDBContainer() { this(IMAGE + ":" + DEFAULT_TAG); } + /** + * @deprecated use {@link MariaDBContainer(DockerImageName)} instead + */ + @Deprecated public MariaDBContainer(String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public MariaDBContainer(final DockerImageName dockerImageName) { super(dockerImageName); addExposedPort(MARIADB_PORT); } diff --git a/modules/mariadb/src/main/java/org/testcontainers/containers/MariaDBContainerProvider.java b/modules/mariadb/src/main/java/org/testcontainers/containers/MariaDBContainerProvider.java index 86f30ee59e5..4330465a9c3 100644 --- a/modules/mariadb/src/main/java/org/testcontainers/containers/MariaDBContainerProvider.java +++ b/modules/mariadb/src/main/java/org/testcontainers/containers/MariaDBContainerProvider.java @@ -1,8 +1,7 @@ package org.testcontainers.containers; import org.testcontainers.jdbc.ConnectionUrl; - -import java.util.Objects; +import org.testcontainers.utility.DockerImageName; /** * Factory for MariaDB org.testcontainers.containers. @@ -25,7 +24,7 @@ public JdbcDatabaseContainer newInstance() { @Override public JdbcDatabaseContainer newInstance(String tag) { - return new MariaDBContainer(MariaDBContainer.IMAGE + ":" + tag); + return new MariaDBContainer(DockerImageName.parse(MariaDBContainer.IMAGE).withTag(tag)); } @Override diff --git a/modules/mariadb/src/test/java/org/testcontainers/MariaDBTestImages.java b/modules/mariadb/src/test/java/org/testcontainers/MariaDBTestImages.java new file mode 100644 index 00000000000..7d18f2f8365 --- /dev/null +++ b/modules/mariadb/src/test/java/org/testcontainers/MariaDBTestImages.java @@ -0,0 +1,7 @@ +package org.testcontainers; + +import org.testcontainers.utility.DockerImageName; + +public interface MariaDBTestImages { + DockerImageName MARIADB_IMAGE = DockerImageName.parse("mariadb:10.3.6"); +} diff --git a/modules/mariadb/src/test/java/org/testcontainers/containers/MariaDBR2DBCDatabaseContainerTest.java b/modules/mariadb/src/test/java/org/testcontainers/containers/MariaDBR2DBCDatabaseContainerTest.java index 30e8cad9c32..b6fb4dd659e 100644 --- a/modules/mariadb/src/test/java/org/testcontainers/containers/MariaDBR2DBCDatabaseContainerTest.java +++ b/modules/mariadb/src/test/java/org/testcontainers/containers/MariaDBR2DBCDatabaseContainerTest.java @@ -2,6 +2,7 @@ import io.r2dbc.spi.ConnectionFactoryOptions; import org.testcontainers.r2dbc.AbstractR2DBCDatabaseContainerTest; +import org.testcontainers.utility.DockerImageName; public class MariaDBR2DBCDatabaseContainerTest extends AbstractR2DBCDatabaseContainerTest> { @@ -17,7 +18,7 @@ protected String createR2DBCUrl() { @Override protected MariaDBContainer createContainer() { - return new MariaDBContainer<>(); + return new MariaDBContainer<>(DockerImageName.parse("mariadb:10.3.6")); } } diff --git a/modules/mariadb/src/test/java/org/testcontainers/junit/mariadb/SimpleMariaDBTest.java b/modules/mariadb/src/test/java/org/testcontainers/junit/mariadb/SimpleMariaDBTest.java index af503ce424b..4ea98bbe1fe 100644 --- a/modules/mariadb/src/test/java/org/testcontainers/junit/mariadb/SimpleMariaDBTest.java +++ b/modules/mariadb/src/test/java/org/testcontainers/junit/mariadb/SimpleMariaDBTest.java @@ -13,13 +13,14 @@ import static org.junit.Assume.assumeFalse; import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.testcontainers.MariaDBTestImages.MARIADB_IMAGE; public class SimpleMariaDBTest extends AbstractContainerDatabaseTest { @Test public void testSimple() throws SQLException { - try (MariaDBContainer mariadb = new MariaDBContainer<>()) { + try (MariaDBContainer mariadb = new MariaDBContainer<>(MARIADB_IMAGE)) { mariadb.start(); @@ -32,7 +33,7 @@ public void testSimple() throws SQLException { @Test public void testSpecificVersion() throws SQLException { - try (MariaDBContainer mariadbOldVersion = new MariaDBContainer<>("mariadb:5.5.51")) { + try (MariaDBContainer mariadbOldVersion = new MariaDBContainer<>(MARIADB_IMAGE.withTag("5.5.51"))) { mariadbOldVersion.start(); @@ -47,7 +48,7 @@ public void testSpecificVersion() throws SQLException { public void testMariaDBWithCustomIniFile() throws SQLException { assumeFalse(SystemUtils.IS_OS_WINDOWS); - try (MariaDBContainer mariadbCustomConfig = new MariaDBContainer<>("mariadb:10.1.16") + try (MariaDBContainer mariadbCustomConfig = new MariaDBContainer<>(MARIADB_IMAGE.withTag("10.1.16")) .withConfigurationOverride("somepath/mariadb_conf_override")) { mariadbCustomConfig.start(); @@ -61,7 +62,7 @@ public void testMariaDBWithCustomIniFile() throws SQLException { @Test public void testMariaDBWithCommandOverride() throws SQLException { - try (MariaDBContainer mariadbCustomConfig = new MariaDBContainer<>("mariadb:10.1.16") + try (MariaDBContainer mariadbCustomConfig = new MariaDBContainer<>(MARIADB_IMAGE) .withCommand("mysqld --auto_increment_increment=10")) { mariadbCustomConfig.start(); ResultSet resultSet = performQuery(mariadbCustomConfig, "show variables like 'auto_increment_increment'"); @@ -73,7 +74,7 @@ public void testMariaDBWithCommandOverride() throws SQLException { @Test public void testWithAdditionalUrlParamInJdbcUrl() { - MariaDBContainer mariaDBContainer = (MariaDBContainer) new MariaDBContainer() + MariaDBContainer mariaDBContainer = new MariaDBContainer<>(MARIADB_IMAGE) .withUrlParam("connectTimeout", "40000") .withUrlParam("rewriteBatchedStatements", "true"); diff --git a/modules/mockserver/src/main/java/org/testcontainers/containers/MockServerContainer.java b/modules/mockserver/src/main/java/org/testcontainers/containers/MockServerContainer.java index e35370f4b27..2aa33931d07 100644 --- a/modules/mockserver/src/main/java/org/testcontainers/containers/MockServerContainer.java +++ b/modules/mockserver/src/main/java/org/testcontainers/containers/MockServerContainer.java @@ -1,6 +1,7 @@ package org.testcontainers.containers; import lombok.extern.slf4j.Slf4j; +import org.testcontainers.utility.DockerImageName; @Slf4j public class MockServerContainer extends GenericContainer { @@ -9,12 +10,24 @@ public class MockServerContainer extends GenericContainer { public static final int PORT = 1080; + /** + * @deprecated use {@link MockServerContainer(DockerImageName)} instead + */ + @Deprecated public MockServerContainer() { this(VERSION); } + /** + * @deprecated use {@link MockServerContainer(DockerImageName)} instead + */ + @Deprecated public MockServerContainer(String version) { - super("jamesdbloom/mockserver:mockserver-" + version); + this(DockerImageName.parse("jamesdbloom/mockserver:mockserver-" + version)); + } + + public MockServerContainer(DockerImageName dockerImageName) { + super(dockerImageName); withCommand("-logLevel INFO -serverPort " + PORT); addExposedPorts(PORT); } diff --git a/modules/mockserver/src/test/java/org/testcontainers/containers/MockServerContainerTest.java b/modules/mockserver/src/test/java/org/testcontainers/containers/MockServerContainerTest.java index 91f740b4bd8..e4d11ed3f39 100644 --- a/modules/mockserver/src/test/java/org/testcontainers/containers/MockServerContainerTest.java +++ b/modules/mockserver/src/test/java/org/testcontainers/containers/MockServerContainerTest.java @@ -4,6 +4,7 @@ import org.junit.Rule; import org.junit.Test; import org.mockserver.client.MockServerClient; +import org.testcontainers.utility.DockerImageName; import java.io.BufferedReader; import java.io.IOException; @@ -19,9 +20,11 @@ public class MockServerContainerTest { + public static final DockerImageName MOCKSERVER_IMAGE = DockerImageName.parse("jamesdbloom/mockserver:mockserver-5.5.4"); + // creatingProxy { @Rule - public MockServerContainer mockServer = new MockServerContainer(); + public MockServerContainer mockServer = new MockServerContainer(MOCKSERVER_IMAGE); // } private static String responseFromMockserver(MockServerContainer mockServer, String path) throws IOException { @@ -52,7 +55,7 @@ public void shouldReturnExpectation() throws Exception { @Test public void shouldCallActualMockserverVersion() throws Exception { String actualVersion = MockServerClient.class.getPackage().getImplementationVersion(); - try (MockServerContainer mockServer = new MockServerContainer(actualVersion)) { + try (MockServerContainer mockServer = new MockServerContainer(MOCKSERVER_IMAGE.withTag("mockserver-" + actualVersion))) { mockServer.start(); String expectedBody = "Hello World!"; diff --git a/modules/mongodb/src/main/java/org/testcontainers/containers/MongoDBContainer.java b/modules/mongodb/src/main/java/org/testcontainers/containers/MongoDBContainer.java index a7f57d310f2..1527b3924db 100644 --- a/modules/mongodb/src/main/java/org/testcontainers/containers/MongoDBContainer.java +++ b/modules/mongodb/src/main/java/org/testcontainers/containers/MongoDBContainer.java @@ -5,6 +5,7 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; import java.io.IOException; @@ -21,11 +22,23 @@ public class MongoDBContainer extends GenericContainer { private static final String MONGODB_VERSION_DEFAULT = "4.0.10"; private static final String MONGODB_DATABASE_NAME_DEFAULT = "test"; + /** + * @deprecated use {@link MongoDBContainer(DockerImageName)} instead + */ + @Deprecated public MongoDBContainer() { this("mongo:" + MONGODB_VERSION_DEFAULT); } + /** + * @deprecated use {@link MongoDBContainer(DockerImageName)} instead + */ + @Deprecated public MongoDBContainer(@NonNull final String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public MongoDBContainer(final DockerImageName dockerImageName) { super(dockerImageName); withExposedPorts(MONGODB_INTERNAL_PORT); withCommand("--replSet", "docker-rs"); diff --git a/modules/mongodb/src/test/java/org/testcontainers/containers/MongoDBContainerTest.java b/modules/mongodb/src/test/java/org/testcontainers/containers/MongoDBContainerTest.java index 7c4f4c12408..d637cb07f2d 100644 --- a/modules/mongodb/src/test/java/org/testcontainers/containers/MongoDBContainerTest.java +++ b/modules/mongodb/src/test/java/org/testcontainers/containers/MongoDBContainerTest.java @@ -11,12 +11,14 @@ import com.mongodb.client.TransactionBody; import org.bson.Document; import org.junit.Test; +import org.testcontainers.utility.DockerImageName; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; public class MongoDBContainerTest { + /** * Taken from https://docs.mongodb.com */ @@ -24,7 +26,7 @@ public class MongoDBContainerTest { public void shouldExecuteTransactions() { try ( // creatingMongoDBContainer { - final MongoDBContainer mongoDBContainer = new MongoDBContainer() + final MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10")) // } ) { diff --git a/modules/mssqlserver/src/main/java/org/testcontainers/containers/MSSQLServerContainer.java b/modules/mssqlserver/src/main/java/org/testcontainers/containers/MSSQLServerContainer.java index 7550f820d51..0a6d8149e34 100644 --- a/modules/mssqlserver/src/main/java/org/testcontainers/containers/MSSQLServerContainer.java +++ b/modules/mssqlserver/src/main/java/org/testcontainers/containers/MSSQLServerContainer.java @@ -1,5 +1,6 @@ package org.testcontainers.containers; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.LicenseAcceptance; import java.util.regex.Pattern; @@ -32,11 +33,23 @@ public class MSSQLServerContainer> exten Pattern.compile("[^a-zA-Z0-9]+", Pattern.CASE_INSENSITIVE) }; + /** + * @deprecated use {@link MSSQLServerContainer(DockerImageName)} instead + */ + @Deprecated public MSSQLServerContainer() { this(IMAGE + ":" + DEFAULT_TAG); } + /** + * @deprecated use {@link MSSQLServerContainer(DockerImageName)} instead + */ + @Deprecated public MSSQLServerContainer(final String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public MSSQLServerContainer(final DockerImageName dockerImageName) { super(dockerImageName); withStartupTimeoutSeconds(DEFAULT_STARTUP_TIMEOUT_SECONDS); withConnectTimeoutSeconds(DEFAULT_CONNECT_TIMEOUT_SECONDS); diff --git a/modules/mssqlserver/src/main/java/org/testcontainers/containers/MSSQLServerContainerProvider.java b/modules/mssqlserver/src/main/java/org/testcontainers/containers/MSSQLServerContainerProvider.java index daaa82ee771..c3495c8a3a6 100644 --- a/modules/mssqlserver/src/main/java/org/testcontainers/containers/MSSQLServerContainerProvider.java +++ b/modules/mssqlserver/src/main/java/org/testcontainers/containers/MSSQLServerContainerProvider.java @@ -1,5 +1,7 @@ package org.testcontainers.containers; +import org.testcontainers.utility.DockerImageName; + /** * Factory for MS SQL Server containers. */ @@ -16,6 +18,6 @@ public JdbcDatabaseContainer newInstance() { @Override public JdbcDatabaseContainer newInstance(String tag) { - return new MSSQLServerContainer(MSSQLServerContainer.IMAGE + ":" + tag); + return new MSSQLServerContainer(DockerImageName.parse(MSSQLServerContainer.IMAGE).withTag(tag)); } } diff --git a/modules/mssqlserver/src/test/java/org/testcontainers/MSSQLServerTestImages.java b/modules/mssqlserver/src/test/java/org/testcontainers/MSSQLServerTestImages.java new file mode 100644 index 00000000000..0cec042e19f --- /dev/null +++ b/modules/mssqlserver/src/test/java/org/testcontainers/MSSQLServerTestImages.java @@ -0,0 +1,7 @@ +package org.testcontainers; + +import org.testcontainers.utility.DockerImageName; + +public interface MSSQLServerTestImages { + DockerImageName MSSQL_SERVER_IMAGE = DockerImageName.parse("mcr.microsoft.com/mssql/server:2017-CU12"); +} diff --git a/modules/mssqlserver/src/test/java/org/testcontainers/containers/MSSQLR2DBCDatabaseContainerTest.java b/modules/mssqlserver/src/test/java/org/testcontainers/containers/MSSQLR2DBCDatabaseContainerTest.java index 1fcf2dd293b..8c0c9ab1c2b 100644 --- a/modules/mssqlserver/src/test/java/org/testcontainers/containers/MSSQLR2DBCDatabaseContainerTest.java +++ b/modules/mssqlserver/src/test/java/org/testcontainers/containers/MSSQLR2DBCDatabaseContainerTest.java @@ -1,6 +1,7 @@ package org.testcontainers.containers; import io.r2dbc.spi.ConnectionFactoryOptions; +import org.testcontainers.MSSQLServerTestImages; import org.testcontainers.r2dbc.AbstractR2DBCDatabaseContainerTest; public class MSSQLR2DBCDatabaseContainerTest extends AbstractR2DBCDatabaseContainerTest> { @@ -17,6 +18,6 @@ protected String createR2DBCUrl() { @Override protected MSSQLServerContainer createContainer() { - return new MSSQLServerContainer<>(); + return new MSSQLServerContainer<>(MSSQLServerTestImages.MSSQL_SERVER_IMAGE); } } diff --git a/modules/mssqlserver/src/test/java/org/testcontainers/junit/mssqlserver/CustomPasswordMSSQLServerTest.java b/modules/mssqlserver/src/test/java/org/testcontainers/junit/mssqlserver/CustomPasswordMSSQLServerTest.java index 0e1ea05b31d..3df8ff0fa3d 100644 --- a/modules/mssqlserver/src/test/java/org/testcontainers/junit/mssqlserver/CustomPasswordMSSQLServerTest.java +++ b/modules/mssqlserver/src/test/java/org/testcontainers/junit/mssqlserver/CustomPasswordMSSQLServerTest.java @@ -4,6 +4,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import org.testcontainers.MSSQLServerTestImages; import org.testcontainers.containers.MSSQLServerContainer; import java.util.Arrays; @@ -66,7 +67,7 @@ public static Collection data() { @Test public void runPasswordTests() { try { - new MSSQLServerContainer<>().withPassword(this.password); + new MSSQLServerContainer<>(MSSQLServerTestImages.MSSQL_SERVER_IMAGE).withPassword(this.password); if (!valid) fail("Password " + this.password + " is not valid. Expected exception"); } catch (IllegalArgumentException e) { diff --git a/modules/mssqlserver/src/test/java/org/testcontainers/junit/mssqlserver/CustomizableMSSQLServerTest.java b/modules/mssqlserver/src/test/java/org/testcontainers/junit/mssqlserver/CustomizableMSSQLServerTest.java index ecbc4e31714..d3c387e7b4a 100644 --- a/modules/mssqlserver/src/test/java/org/testcontainers/junit/mssqlserver/CustomizableMSSQLServerTest.java +++ b/modules/mssqlserver/src/test/java/org/testcontainers/junit/mssqlserver/CustomizableMSSQLServerTest.java @@ -3,6 +3,7 @@ import org.junit.Test; import org.testcontainers.containers.MSSQLServerContainer; import org.testcontainers.db.AbstractContainerDatabaseTest; +import org.testcontainers.utility.DockerImageName; import java.sql.ResultSet; import java.sql.SQLException; @@ -15,7 +16,7 @@ public class CustomizableMSSQLServerTest extends AbstractContainerDatabaseTest { @Test public void testSqlServerConnection() throws SQLException { - try (MSSQLServerContainer mssqlServerContainer = new MSSQLServerContainer<>() + try (MSSQLServerContainer mssqlServerContainer = new MSSQLServerContainer<>(DockerImageName.parse("mcr.microsoft.com/mssql/server:2017-CU12")) .withPassword(STRONG_PASSWORD)) { mssqlServerContainer.start(); diff --git a/modules/mssqlserver/src/test/java/org/testcontainers/junit/mssqlserver/SimpleMSSQLServerTest.java b/modules/mssqlserver/src/test/java/org/testcontainers/junit/mssqlserver/SimpleMSSQLServerTest.java index 71e12a6d864..100b29b34f7 100644 --- a/modules/mssqlserver/src/test/java/org/testcontainers/junit/mssqlserver/SimpleMSSQLServerTest.java +++ b/modules/mssqlserver/src/test/java/org/testcontainers/junit/mssqlserver/SimpleMSSQLServerTest.java @@ -1,6 +1,7 @@ package org.testcontainers.junit.mssqlserver; import org.junit.Test; +import org.testcontainers.MSSQLServerTestImages; import org.testcontainers.containers.MSSQLServerContainer; import org.testcontainers.db.AbstractContainerDatabaseTest; @@ -12,12 +13,13 @@ import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertThat; import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.testcontainers.MSSQLServerTestImages.MSSQL_SERVER_IMAGE; public class SimpleMSSQLServerTest extends AbstractContainerDatabaseTest { @Test public void testSimple() throws SQLException { - try (MSSQLServerContainer mssqlServer = new MSSQLServerContainer<>()) { + try (MSSQLServerContainer mssqlServer = new MSSQLServerContainer<>(MSSQL_SERVER_IMAGE)) { mssqlServer.start(); ResultSet resultSet = performQuery(mssqlServer, "SELECT 1"); @@ -28,7 +30,7 @@ public void testSimple() throws SQLException { @Test public void testWithAdditionalUrlParamInJdbcUrl() { - try (MSSQLServerContainer mssqlServer = new MSSQLServerContainer<>() + try (MSSQLServerContainer mssqlServer = new MSSQLServerContainer<>(MSSQL_SERVER_IMAGE) .withUrlParam("integratedSecurity", "false") .withUrlParam("applicationName", "MyApp")) { @@ -42,7 +44,7 @@ public void testWithAdditionalUrlParamInJdbcUrl() { @Test public void testSetupDatabase() throws SQLException { - try (MSSQLServerContainer mssqlServer = new MSSQLServerContainer<>()) { + try (MSSQLServerContainer mssqlServer = new MSSQLServerContainer<>(MSSQL_SERVER_IMAGE)) { mssqlServer.start(); DataSource ds = getDataSource(mssqlServer); Statement statement = ds.getConnection().createStatement(); diff --git a/modules/mysql/src/main/java/org/testcontainers/containers/MySQLContainer.java b/modules/mysql/src/main/java/org/testcontainers/containers/MySQLContainer.java index 1ef574cbd5e..35321db5d72 100644 --- a/modules/mysql/src/main/java/org/testcontainers/containers/MySQLContainer.java +++ b/modules/mysql/src/main/java/org/testcontainers/containers/MySQLContainer.java @@ -1,12 +1,11 @@ package org.testcontainers.containers; import org.jetbrains.annotations.NotNull; +import org.testcontainers.utility.DockerImageName; import java.util.HashSet; import java.util.Set; -import static java.util.stream.Collectors.joining; - /** * @author richardnorth */ @@ -27,15 +26,28 @@ public class MySQLContainer> extends JdbcDatab private String password = DEFAULT_PASSWORD; private static final String MYSQL_ROOT_USER = "root"; + /** + * @deprecated use {@link MySQLContainer(DockerImageName)} instead + */ + @Deprecated public MySQLContainer() { this(IMAGE + ":" + DEFAULT_TAG); } + /** + * @deprecated use {@link MySQLContainer(DockerImageName)} instead + */ + @Deprecated public MySQLContainer(String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public MySQLContainer(final DockerImageName dockerImageName) { super(dockerImageName); addExposedPort(MYSQL_PORT); } + @NotNull @Override protected Set getLivenessCheckPorts() { diff --git a/modules/mysql/src/main/java/org/testcontainers/containers/MySQLContainerProvider.java b/modules/mysql/src/main/java/org/testcontainers/containers/MySQLContainerProvider.java index 7d4919f4b26..18d126635b1 100644 --- a/modules/mysql/src/main/java/org/testcontainers/containers/MySQLContainerProvider.java +++ b/modules/mysql/src/main/java/org/testcontainers/containers/MySQLContainerProvider.java @@ -1,8 +1,7 @@ package org.testcontainers.containers; import org.testcontainers.jdbc.ConnectionUrl; - -import java.util.Objects; +import org.testcontainers.utility.DockerImageName; /** * Factory for MySQL containers. @@ -26,7 +25,7 @@ public JdbcDatabaseContainer newInstance() { @Override public JdbcDatabaseContainer newInstance(String tag) { if (tag != null) { - return new MySQLContainer(MySQLContainer.IMAGE + ":" + tag); + return new MySQLContainer(DockerImageName.parse(MySQLContainer.IMAGE).withTag(tag)); } else { return newInstance(); } diff --git a/modules/mysql/src/test/java/org/testcontainers/MySQLTestImages.java b/modules/mysql/src/test/java/org/testcontainers/MySQLTestImages.java new file mode 100644 index 00000000000..6c8c6690d1f --- /dev/null +++ b/modules/mysql/src/test/java/org/testcontainers/MySQLTestImages.java @@ -0,0 +1,9 @@ +package org.testcontainers; + +import org.testcontainers.utility.DockerImageName; + +public class MySQLTestImages { + public static final DockerImageName MYSQL_IMAGE = DockerImageName.parse("mysql:5.7.22"); + public static final DockerImageName MYSQL_55_IMAGE = DockerImageName.parse("mysql:5.5"); + public static final DockerImageName MYSQL_56_IMAGE = DockerImageName.parse("mysql:5.6"); +} diff --git a/modules/mysql/src/test/java/org/testcontainers/containers/MySQLR2DBCDatabaseContainerTest.java b/modules/mysql/src/test/java/org/testcontainers/containers/MySQLR2DBCDatabaseContainerTest.java index 19edc3dbca4..38abf637c3a 100644 --- a/modules/mysql/src/test/java/org/testcontainers/containers/MySQLR2DBCDatabaseContainerTest.java +++ b/modules/mysql/src/test/java/org/testcontainers/containers/MySQLR2DBCDatabaseContainerTest.java @@ -1,6 +1,7 @@ package org.testcontainers.containers; import io.r2dbc.spi.ConnectionFactoryOptions; +import org.testcontainers.MySQLTestImages; import org.testcontainers.r2dbc.AbstractR2DBCDatabaseContainerTest; public class MySQLR2DBCDatabaseContainerTest extends AbstractR2DBCDatabaseContainerTest> { @@ -17,7 +18,7 @@ protected String createR2DBCUrl() { @Override protected MySQLContainer createContainer() { - return new MySQLContainer<>(); + return new MySQLContainer<>(MySQLTestImages.MYSQL_IMAGE); } } diff --git a/modules/mysql/src/test/java/org/testcontainers/junit/mysql/CustomizableMysqlTest.java b/modules/mysql/src/test/java/org/testcontainers/junit/mysql/CustomizableMysqlTest.java index 590d288e3fe..708b2b987cd 100644 --- a/modules/mysql/src/test/java/org/testcontainers/junit/mysql/CustomizableMysqlTest.java +++ b/modules/mysql/src/test/java/org/testcontainers/junit/mysql/CustomizableMysqlTest.java @@ -1,6 +1,7 @@ package org.testcontainers.junit.mysql; import org.junit.Test; +import org.testcontainers.MySQLTestImages; import org.testcontainers.containers.MySQLContainer; import org.testcontainers.db.AbstractContainerDatabaseTest; @@ -17,7 +18,7 @@ public class CustomizableMysqlTest extends AbstractContainerDatabaseTest { @Test public void testSimple() throws SQLException { // Add MYSQL_ROOT_HOST environment so that we can root login from anywhere for testing purposes - try (MySQLContainer mysql = new MySQLContainer<>("mysql:5.5") + try (MySQLContainer mysql = new MySQLContainer<>(MySQLTestImages.MYSQL_IMAGE) .withDatabaseName(DB_NAME) .withUsername(USER) .withPassword(PWD) diff --git a/modules/mysql/src/test/java/org/testcontainers/junit/mysql/MultiVersionMySQLTest.java b/modules/mysql/src/test/java/org/testcontainers/junit/mysql/MultiVersionMySQLTest.java index 3c0c86ffafa..b8f1a136d9a 100644 --- a/modules/mysql/src/test/java/org/testcontainers/junit/mysql/MultiVersionMySQLTest.java +++ b/modules/mysql/src/test/java/org/testcontainers/junit/mysql/MultiVersionMySQLTest.java @@ -3,8 +3,10 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import org.testcontainers.MySQLTestImages; import org.testcontainers.containers.MySQLContainer; import org.testcontainers.db.AbstractContainerDatabaseTest; +import org.testcontainers.utility.DockerImageName; import java.sql.ResultSet; import java.sql.SQLException; @@ -27,7 +29,10 @@ public MultiVersionMySQLTest(String version) { @Test public void versionCheckTest() throws SQLException { - try (MySQLContainer mysql = new MySQLContainer<>("mysql:" + version)) { + + final DockerImageName dockerImageName = MySQLTestImages.MYSQL_IMAGE.withTag(version); + + try (MySQLContainer mysql = new MySQLContainer<>(dockerImageName)) { mysql.start(); final ResultSet resultSet = performQuery(mysql, "SELECT VERSION()"); final String resultSetString = resultSet.getString(1); diff --git a/modules/mysql/src/test/java/org/testcontainers/junit/mysql/SimpleMySQLTest.java b/modules/mysql/src/test/java/org/testcontainers/junit/mysql/SimpleMySQLTest.java index 6d6f8d26453..f0ceeb92a48 100644 --- a/modules/mysql/src/test/java/org/testcontainers/junit/mysql/SimpleMySQLTest.java +++ b/modules/mysql/src/test/java/org/testcontainers/junit/mysql/SimpleMySQLTest.java @@ -20,10 +20,13 @@ import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; import static org.junit.Assume.assumeFalse; import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; +import static org.rnorth.visibleassertions.VisibleAssertions.fail; +import static org.testcontainers.MySQLTestImages.MYSQL_55_IMAGE; +import static org.testcontainers.MySQLTestImages.MYSQL_56_IMAGE; +import static org.testcontainers.MySQLTestImages.MYSQL_IMAGE; public class SimpleMySQLTest extends AbstractContainerDatabaseTest { @@ -37,19 +40,19 @@ public class SimpleMySQLTest extends AbstractContainerDatabaseTest { */ /* @ClassRule - public static MySQLContainer mysql = new MySQLContainer<>(); + public static MySQLContainer mysql = new MySQLContainer<>(MYSQL_IMAGE); @ClassRule - public static MySQLContainer mysqlOldVersion = new MySQLContainer<>("mysql:5.5"); + public static MySQLContainer mysqlOldVersion = new MySQLContainer<>(DockerImageName.parse("mysql:5.5");) @ClassRule - public static MySQLContainer mysqlCustomConfig = new MySQLContainer<>("mysql:5.6") + public static MySQLContainer mysqlCustomConfig = new MySQLContainer<>(DockerImageName.parse("mysql:5.6")) .withConfigurationOverride("somepath/mysql_conf_override"); */ @Test public void testSimple() throws SQLException { - try (MySQLContainer mysql = new MySQLContainer<>() + try (MySQLContainer mysql = new MySQLContainer<>(MYSQL_IMAGE) .withConfigurationOverride("somepath/mysql_conf_override") .withLogConsumer(new Slf4jLogConsumer(logger))) { @@ -64,7 +67,7 @@ public void testSimple() throws SQLException { @Test public void testSpecificVersion() throws SQLException { - try (MySQLContainer mysqlOldVersion = new MySQLContainer<>("mysql:5.5") + try (MySQLContainer mysqlOldVersion = new MySQLContainer<>(MYSQL_55_IMAGE) .withConfigurationOverride("somepath/mysql_conf_override") .withLogConsumer(new Slf4jLogConsumer(logger))) { @@ -81,7 +84,7 @@ public void testSpecificVersion() throws SQLException { public void testMySQLWithCustomIniFile() throws SQLException { assumeFalse(SystemUtils.IS_OS_WINDOWS); - try (MySQLContainer mysqlCustomConfig = new MySQLContainer<>("mysql:5.6") + try (MySQLContainer mysqlCustomConfig = new MySQLContainer<>(MYSQL_56_IMAGE) .withConfigurationOverride("somepath/mysql_conf_override")) { mysqlCustomConfig.start(); @@ -95,7 +98,7 @@ public void testMySQLWithCustomIniFile() throws SQLException { @Test public void testCommandOverride() throws SQLException { - try (MySQLContainer mysqlCustomConfig = new MySQLContainer<>() + try (MySQLContainer mysqlCustomConfig = new MySQLContainer<>(MYSQL_IMAGE) .withCommand("mysqld --auto_increment_increment=42")) { mysqlCustomConfig.start(); @@ -109,7 +112,7 @@ public void testCommandOverride() throws SQLException { @Test public void testExplicitInitScript() throws SQLException { - try (MySQLContainer container = new MySQLContainer<>() + try (MySQLContainer container = new MySQLContainer<>(MYSQL_IMAGE) .withInitScript("somepath/init_mysql.sql") .withLogConsumer(new Slf4jLogConsumer(logger))) { container.start(); @@ -123,7 +126,7 @@ public void testExplicitInitScript() throws SQLException { @Test(expected = ContainerLaunchException.class) public void testEmptyPasswordWithNonRootUser() { - try (MySQLContainer container = new MySQLContainer<>("mysql:5.5") + try (MySQLContainer container = new MySQLContainer<>(MYSQL_55_IMAGE) .withDatabaseName("TEST") .withUsername("test") .withPassword("") @@ -136,7 +139,7 @@ public void testEmptyPasswordWithNonRootUser() { @Test public void testEmptyPasswordWithRootUser() throws SQLException { // Add MYSQL_ROOT_HOST environment so that we can root login from anywhere for testing purposes - try (MySQLContainer mysql = new MySQLContainer<>("mysql:5.5") + try (MySQLContainer mysql = new MySQLContainer<>(MYSQL_55_IMAGE) .withDatabaseName("foo") .withUsername("root") .withPassword("") @@ -153,7 +156,7 @@ public void testEmptyPasswordWithRootUser() throws SQLException { @Test public void testWithAdditionalUrlParamTimeZone() throws SQLException { - MySQLContainer mysql = (MySQLContainer) new MySQLContainer() + MySQLContainer mysql = new MySQLContainer<>(MYSQL_IMAGE) .withUrlParam("serverTimezone", "Europe/Zurich") .withEnv("TZ", "Europe/Zurich") .withLogConsumer(new Slf4jLogConsumer(logger)); @@ -183,7 +186,7 @@ public void testWithAdditionalUrlParamTimeZone() throws SQLException { @Test public void testWithAdditionalUrlParamMultiQueries() throws SQLException { - MySQLContainer mysql = (MySQLContainer) new MySQLContainer() + MySQLContainer mysql = new MySQLContainer<>(MYSQL_IMAGE) .withUrlParam("allowMultiQueries", "true") .withLogConsumer(new Slf4jLogConsumer(logger)); mysql.start(); @@ -207,7 +210,7 @@ public void testWithAdditionalUrlParamMultiQueries() throws SQLException { @Test public void testWithAdditionalUrlParamInJdbcUrl() { - MySQLContainer mysql = (MySQLContainer) new MySQLContainer() + MySQLContainer mysql = new MySQLContainer<>(MYSQL_IMAGE) .withUrlParam("allowMultiQueries", "true") .withUrlParam("rewriteBatchedStatements", "true") .withLogConsumer(new Slf4jLogConsumer(logger)); diff --git a/modules/neo4j/src/main/java/org/testcontainers/containers/Neo4jContainer.java b/modules/neo4j/src/main/java/org/testcontainers/containers/Neo4jContainer.java index 10545da43d6..5d4212ccacd 100644 --- a/modules/neo4j/src/main/java/org/testcontainers/containers/Neo4jContainer.java +++ b/modules/neo4j/src/main/java/org/testcontainers/containers/Neo4jContainer.java @@ -1,19 +1,20 @@ package org.testcontainers.containers; -import static java.net.HttpURLConnection.*; -import static java.util.stream.Collectors.*; - -import java.time.Duration; -import java.util.Set; -import java.util.stream.Stream; - import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; import org.testcontainers.containers.wait.strategy.WaitAllStrategy; import org.testcontainers.containers.wait.strategy.WaitStrategy; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.LicenseAcceptance; import org.testcontainers.utility.MountableFile; +import java.time.Duration; +import java.util.Set; +import java.util.stream.Stream; + +import static java.net.HttpURLConnection.HTTP_OK; +import static java.util.stream.Collectors.toSet; + /** * Testcontainer for Neo4j. * @@ -58,23 +59,29 @@ public class Neo4jContainer> extends GenericContaine private String adminPassword = DEFAULT_ADMIN_PASSWORD; - private boolean defaultImage = false; + private boolean standardImage = false; /** * Creates a Testcontainer using the official Neo4j docker image. + * @deprecated use {@link Neo4jContainer(DockerImageName)} instead */ + @Deprecated public Neo4jContainer() { this(DOCKER_IMAGE_NAME); - - this.defaultImage = true; } /** * Creates a Testcontainer using a specific docker image. * * @param dockerImageName The docker image to use. + * @deprecated use {@link Neo4jContainer(DockerImageName)} instead */ + @Deprecated public Neo4jContainer(String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public Neo4jContainer(final DockerImageName dockerImageName) { super(dockerImageName); WaitStrategy waitForBolt = new LogMessageWaitStrategy() @@ -89,6 +96,10 @@ public Neo4jContainer(String dockerImageName) { .withStartupTimeout(Duration.ofMinutes(2)); addExposedPorts(DEFAULT_BOLT_PORT, DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT); + + if (dockerImageName.getUnversionedPart().equals(DEFAULT_IMAGE_NAME)) { + this.standardImage = true; + } } @Override @@ -139,7 +150,7 @@ public String getHttpsUrl() { */ public S withEnterpriseEdition() { - if (!defaultImage) { + if (!standardImage) { throw new IllegalStateException( String.format("Cannot use enterprise version with alternative image %s.", getDockerImageName())); } diff --git a/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerJUnitIntegrationTest.java b/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerJUnitIntegrationTest.java index 96b7a48b96f..5a67674cbe8 100644 --- a/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerJUnitIntegrationTest.java +++ b/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerJUnitIntegrationTest.java @@ -1,9 +1,5 @@ package org.testcontainers.containers; -import static org.assertj.core.api.Assertions.*; - -import java.util.Collections; - import org.junit.ClassRule; import org.junit.Test; import org.neo4j.driver.v1.AuthTokens; @@ -11,6 +7,11 @@ import org.neo4j.driver.v1.GraphDatabase; import org.neo4j.driver.v1.Session; +import java.util.Collections; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + /** * Test for basic functionality when used as a @ClassRule. * @@ -19,7 +20,7 @@ public class Neo4jContainerJUnitIntegrationTest { @ClassRule - public static Neo4jContainer neo4jContainer = new Neo4jContainer(); + public static Neo4jContainer neo4jContainer = new Neo4jContainer<>(Neo4jTestImages.NEO4J_TEST_IMAGE); @Test public void shouldStart() { diff --git a/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerTest.java b/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerTest.java index cbbe5cb5729..6a32dac0af0 100644 --- a/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerTest.java +++ b/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerTest.java @@ -1,10 +1,5 @@ package org.testcontainers.containers; -import static org.assertj.core.api.Assertions.*; -import static org.assertj.core.api.Assumptions.*; - -import java.util.Collections; - import org.junit.Test; import org.neo4j.driver.v1.AuthToken; import org.neo4j.driver.v1.AuthTokens; @@ -15,6 +10,12 @@ import org.neo4j.driver.v1.StatementResult; import org.testcontainers.utility.MountableFile; +import java.util.Collections; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assumptions.assumeThat; + /** * Tests of functionality special to the Neo4jContainer. * @@ -29,7 +30,7 @@ public class Neo4jContainerTest { public void shouldDisableAuthentication() { try ( - Neo4jContainer neo4jContainer = new Neo4jContainer().withoutAuthentication(); + Neo4jContainer neo4jContainer = new Neo4jContainer<>(Neo4jTestImages.NEO4J_TEST_IMAGE).withoutAuthentication() ) { neo4jContainer.start(); try (Driver driver = getDriver(neo4jContainer); @@ -44,8 +45,8 @@ public void shouldDisableAuthentication() { @Test public void shouldCopyDatabase() { try ( - Neo4jContainer neo4jContainer = new Neo4jContainer() - .withDatabase(MountableFile.forClasspathResource("/test-graph.db")); + Neo4jContainer neo4jContainer = new Neo4jContainer<>(Neo4jTestImages.NEO4J_TEST_IMAGE) + .withDatabase(MountableFile.forClasspathResource("/test-graph.db")) ) { neo4jContainer.start(); try ( @@ -62,8 +63,8 @@ public void shouldCopyDatabase() { @Test public void shouldCopyPlugins() { try ( - Neo4jContainer neo4jContainer = new Neo4jContainer() - .withPlugins(MountableFile.forClasspathResource("/custom-plugins")); + Neo4jContainer neo4jContainer = new Neo4jContainer<>(Neo4jTestImages.NEO4J_TEST_IMAGE) + .withPlugins(MountableFile.forClasspathResource("/custom-plugins")) ) { neo4jContainer.start(); try ( @@ -78,8 +79,8 @@ public void shouldCopyPlugins() { @Test public void shouldCopyPlugin() { try ( - Neo4jContainer neo4jContainer = new Neo4jContainer() - .withPlugins(MountableFile.forClasspathResource("/custom-plugins/hello-world.jar")); + Neo4jContainer neo4jContainer = new Neo4jContainer<>(Neo4jTestImages.NEO4J_TEST_IMAGE) + .withPlugins(MountableFile.forClasspathResource("/custom-plugins/hello-world.jar")) ) { neo4jContainer.start(); try ( @@ -105,7 +106,7 @@ public void shouldCheckEnterpriseLicense() { String expectedImageName = "neo4j:3.5.0-enterprise"; assertThatExceptionOfType(IllegalStateException.class) - .isThrownBy(() -> new Neo4jContainer().withEnterpriseEdition()) + .isThrownBy(() -> new Neo4jContainer<>(Neo4jTestImages.NEO4J_TEST_IMAGE).withEnterpriseEdition()) .withMessageContaining("The image " + expectedImageName + " requires you to accept a license agreement."); } @@ -114,7 +115,7 @@ public void shouldRunEnterprise() { assumeThat(Neo4jContainerTest.class.getResource(ACCEPTANCE_FILE_LOCATION)).isNotNull(); try ( - Neo4jContainer neo4jContainer = new Neo4jContainer() + Neo4jContainer neo4jContainer = new Neo4jContainer<>(Neo4jTestImages.NEO4J_TEST_IMAGE) .withEnterpriseEdition() .withAdminPassword("Picard123") ) { @@ -134,7 +135,7 @@ public void shouldRunEnterprise() { @Test public void shouldAddConfigToEnvironment() { - Neo4jContainer neo4jContainer = new Neo4jContainer() + Neo4jContainer neo4jContainer = new Neo4jContainer<>(Neo4jTestImages.NEO4J_TEST_IMAGE) .withNeo4jConfig("dbms.security.procedures.unrestricted", "apoc.*,algo.*") .withNeo4jConfig("dbms.tx_log.rotation.size", "42M"); @@ -144,7 +145,7 @@ public void shouldAddConfigToEnvironment() { .containsEntry("NEO4J_dbms_tx__log_rotation_size", "42M"); } - private static Driver getDriver(Neo4jContainer container) { + private static Driver getDriver(Neo4jContainer container) { AuthToken authToken = AuthTokens.none(); if (container.getAdminPassword() != null) { diff --git a/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jTestImages.java b/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jTestImages.java new file mode 100644 index 00000000000..2cab24baf2b --- /dev/null +++ b/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jTestImages.java @@ -0,0 +1,7 @@ +package org.testcontainers.containers; + +import org.testcontainers.utility.DockerImageName; + +public interface Neo4jTestImages { + DockerImageName NEO4J_TEST_IMAGE = DockerImageName.parse("neo4j:3.5.0"); +} diff --git a/modules/nginx/src/main/java/org/testcontainers/containers/NginxContainer.java b/modules/nginx/src/main/java/org/testcontainers/containers/NginxContainer.java index fb931bce409..75a4571b68e 100644 --- a/modules/nginx/src/main/java/org/testcontainers/containers/NginxContainer.java +++ b/modules/nginx/src/main/java/org/testcontainers/containers/NginxContainer.java @@ -2,6 +2,7 @@ import org.jetbrains.annotations.NotNull; import org.testcontainers.containers.traits.LinkableContainer; +import org.testcontainers.utility.DockerImageName; import java.net.MalformedURLException; import java.net.URL; @@ -15,17 +16,29 @@ public class NginxContainer> extends GenericCo private static final int NGINX_DEFAULT_PORT = 80; + /** + * @deprecated use {@link NginxContainer(DockerImageName)} instead + */ + @Deprecated public NginxContainer() { this("nginx:1.9.4"); } + /** + * @deprecated use {@link NginxContainer(DockerImageName)} instead + */ + @Deprecated public NginxContainer(String dockerImageName) { - super(dockerImageName); + this(DockerImageName.parse(dockerImageName)); addExposedPort(NGINX_DEFAULT_PORT); setCommand("nginx", "-g", "daemon off;"); } + public NginxContainer(final DockerImageName dockerImageName) { + super(dockerImageName); + } + @NotNull @Override protected Set getLivenessCheckPorts() { diff --git a/modules/nginx/src/test/java/org/testcontainers/junit/SimpleNginxTest.java b/modules/nginx/src/test/java/org/testcontainers/junit/SimpleNginxTest.java index b41a0d8361e..e322804bf75 100644 --- a/modules/nginx/src/test/java/org/testcontainers/junit/SimpleNginxTest.java +++ b/modules/nginx/src/test/java/org/testcontainers/junit/SimpleNginxTest.java @@ -6,6 +6,7 @@ import org.junit.Test; import org.testcontainers.containers.NginxContainer; import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; +import org.testcontainers.utility.DockerImageName; import java.io.*; import java.net.URL; @@ -19,11 +20,13 @@ */ public class SimpleNginxTest { + private static final DockerImageName NGINX_IMAGE = DockerImageName.parse("nginx:1.9.4"); + private static String tmpDirectory = System.getProperty("user.home") + "/.tmp-test-container"; // creatingContainer { @Rule - public NginxContainer nginx = new NginxContainer<>() + public NginxContainer nginx = new NginxContainer<>(NGINX_IMAGE) .withCustomContent(tmpDirectory) .waitingFor(new HttpWaitStrategy()); // } diff --git a/modules/oracle-xe/src/main/java/org/testcontainers/containers/OracleContainer.java b/modules/oracle-xe/src/main/java/org/testcontainers/containers/OracleContainer.java index d263a141d4f..8406d8275fb 100644 --- a/modules/oracle-xe/src/main/java/org/testcontainers/containers/OracleContainer.java +++ b/modules/oracle-xe/src/main/java/org/testcontainers/containers/OracleContainer.java @@ -1,5 +1,6 @@ package org.testcontainers.containers; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.TestcontainersConfiguration; import java.util.concurrent.Future; @@ -32,11 +33,23 @@ private static String resolveImageName() { return image; } + /** + * @deprecated use {@link OracleContainer(DockerImageName)} instead + */ + @Deprecated public OracleContainer() { this(resolveImageName()); } + /** + * @deprecated use {@link OracleContainer(DockerImageName)} instead + */ + @Deprecated public OracleContainer(String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public OracleContainer(final DockerImageName dockerImageName) { super(dockerImageName); preconfigure(); } diff --git a/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java b/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java index b7fcc85573a..797f73f7159 100644 --- a/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java +++ b/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java @@ -13,6 +13,7 @@ import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.containers.wait.strategy.WaitAllStrategy; import org.testcontainers.containers.wait.strategy.WaitStrategy; +import org.testcontainers.utility.DockerImageName; import java.io.IOException; import java.net.URL; @@ -48,11 +49,23 @@ public class OrientDBContainer extends GenericContainer { private OrientDB orientDB; private ODatabaseSession session; + /** + * @deprecated use {@link OrientDBContainer(DockerImageName)} instead + */ + @Deprecated public OrientDBContainer() { this(DOCKER_IMAGE_NAME); } + /** + * @deprecated use {@link OrientDBContainer(DockerImageName)} instead + */ + @Deprecated public OrientDBContainer(@NonNull String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public OrientDBContainer(final DockerImageName dockerImageName) { super(dockerImageName); serverPassword = DEFAULT_SERVER_PASSWORD; diff --git a/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java b/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java index 54b0661cae2..60d7b172436 100644 --- a/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java +++ b/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java @@ -2,6 +2,7 @@ import com.orientechnologies.orient.core.db.ODatabaseSession; import org.junit.Test; +import org.testcontainers.utility.DockerImageName; import static org.assertj.core.api.Assertions.*; @@ -10,9 +11,11 @@ */ public class OrientDBContainerTest { + private static final DockerImageName ORIENTDB_IMAGE = DockerImageName.parse("orientdb:3.0.24-tp3"); + @Test public void shouldReturnTheSameSession() { - try (OrientDBContainer container = new OrientDBContainer()) { + try (OrientDBContainer container = new OrientDBContainer(ORIENTDB_IMAGE)) { container.start(); final ODatabaseSession session = container.getSession(); @@ -24,7 +27,7 @@ public void shouldReturnTheSameSession() { @Test public void shouldInitializeWithCommands() { - try (OrientDBContainer container = new OrientDBContainer()) { + try (OrientDBContainer container = new OrientDBContainer(ORIENTDB_IMAGE)) { container.start(); final ODatabaseSession session = container.getSession(); @@ -40,7 +43,7 @@ public void shouldInitializeWithCommands() { @Test public void shouldQueryWithGremlin() { - try (OrientDBContainer container = new OrientDBContainer()) { + try (OrientDBContainer container = new OrientDBContainer(ORIENTDB_IMAGE)) { container.start(); final ODatabaseSession session = container.getSession("admin", "admin"); @@ -56,7 +59,7 @@ public void shouldQueryWithGremlin() { @Test public void shouldInitializeDatabaseFromScript() { - try (OrientDBContainer container = new OrientDBContainer() + try (OrientDBContainer container = new OrientDBContainer(ORIENTDB_IMAGE) .withScriptPath("initscript.osql") .withDatabaseName("persons")) { diff --git a/modules/postgresql/src/main/java/org/testcontainers/containers/PostgisContainerProvider.java b/modules/postgresql/src/main/java/org/testcontainers/containers/PostgisContainerProvider.java index 54c87a84648..9e59787837b 100644 --- a/modules/postgresql/src/main/java/org/testcontainers/containers/PostgisContainerProvider.java +++ b/modules/postgresql/src/main/java/org/testcontainers/containers/PostgisContainerProvider.java @@ -1,8 +1,7 @@ package org.testcontainers.containers; import org.testcontainers.jdbc.ConnectionUrl; - -import java.util.Objects; +import org.testcontainers.utility.DockerImageName; /** * Factory for PostGIS containers, which are a special flavour of PostgreSQL. @@ -28,7 +27,7 @@ public JdbcDatabaseContainer newInstance() { @Override public JdbcDatabaseContainer newInstance(String tag) { - return new PostgreSQLContainer(DEFAULT_IMAGE + ":" + tag); + return new PostgreSQLContainer(DockerImageName.parse(DEFAULT_IMAGE).withTag(DEFAULT_TAG)); } @Override diff --git a/modules/postgresql/src/main/java/org/testcontainers/containers/PostgreSQLContainer.java b/modules/postgresql/src/main/java/org/testcontainers/containers/PostgreSQLContainer.java index 1c814044023..b1ddb2a26ee 100644 --- a/modules/postgresql/src/main/java/org/testcontainers/containers/PostgreSQLContainer.java +++ b/modules/postgresql/src/main/java/org/testcontainers/containers/PostgreSQLContainer.java @@ -2,6 +2,7 @@ import org.jetbrains.annotations.NotNull; import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; +import org.testcontainers.utility.DockerImageName; import java.time.Duration; import java.util.HashSet; @@ -31,11 +32,23 @@ public class PostgreSQLContainer> extends private static final String QUERY_PARAM_SEPARATOR = "&"; + /** + * @deprecated use {@link PostgreSQLContainer(DockerImageName)} instead + */ + @Deprecated public PostgreSQLContainer() { this(IMAGE + ":" + DEFAULT_TAG); } + /** + * @deprecated use {@link PostgreSQLContainer(DockerImageName)} instead + */ + @Deprecated public PostgreSQLContainer(final String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public PostgreSQLContainer(final DockerImageName dockerImageName) { super(dockerImageName); this.waitStrategy = new LogMessageWaitStrategy() .withRegEx(".*database system is ready to accept connections.*\\s") diff --git a/modules/postgresql/src/main/java/org/testcontainers/containers/PostgreSQLContainerProvider.java b/modules/postgresql/src/main/java/org/testcontainers/containers/PostgreSQLContainerProvider.java index 77a0329c22c..5e7580c75eb 100644 --- a/modules/postgresql/src/main/java/org/testcontainers/containers/PostgreSQLContainerProvider.java +++ b/modules/postgresql/src/main/java/org/testcontainers/containers/PostgreSQLContainerProvider.java @@ -1,8 +1,7 @@ package org.testcontainers.containers; import org.testcontainers.jdbc.ConnectionUrl; - -import java.util.Objects; +import org.testcontainers.utility.DockerImageName; /** * Factory for PostgreSQL containers. @@ -24,7 +23,7 @@ public JdbcDatabaseContainer newInstance() { @Override public JdbcDatabaseContainer newInstance(String tag) { - return new PostgreSQLContainer(PostgreSQLContainer.IMAGE + ":" + tag); + return new PostgreSQLContainer(DockerImageName.parse(PostgreSQLContainer.IMAGE).withTag(tag)); } @Override diff --git a/modules/postgresql/src/test/java/org/testcontainers/PostgreSQLTestImages.java b/modules/postgresql/src/test/java/org/testcontainers/PostgreSQLTestImages.java new file mode 100644 index 00000000000..8be01053570 --- /dev/null +++ b/modules/postgresql/src/test/java/org/testcontainers/PostgreSQLTestImages.java @@ -0,0 +1,7 @@ +package org.testcontainers; + +import org.testcontainers.utility.DockerImageName; + +public interface PostgreSQLTestImages { + DockerImageName POSTGRES_TEST_IMAGE = DockerImageName.parse("postgres:9.6.12"); +} diff --git a/modules/postgresql/src/test/java/org/testcontainers/containers/PostgreSQLConnectionURLTest.java b/modules/postgresql/src/test/java/org/testcontainers/containers/PostgreSQLConnectionURLTest.java index c0ba7e40d44..c18f19a109e 100644 --- a/modules/postgresql/src/test/java/org/testcontainers/containers/PostgreSQLConnectionURLTest.java +++ b/modules/postgresql/src/test/java/org/testcontainers/containers/PostgreSQLConnectionURLTest.java @@ -1,6 +1,7 @@ package org.testcontainers.containers; import org.junit.Test; +import org.testcontainers.PostgreSQLTestImages; import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; import static org.rnorth.visibleassertions.VisibleAssertions.assertFalse; @@ -46,6 +47,9 @@ public void shouldRejectInvalidQueryString() { } static class FixedJdbcUrlPostgreSQLContainer extends PostgreSQLContainer { + public FixedJdbcUrlPostgreSQLContainer() { + super(PostgreSQLTestImages.POSTGRES_TEST_IMAGE); + } @Override public String getHost() { @@ -59,6 +63,9 @@ public Integer getMappedPort(int originalPort) { } static class NoParamsUrlPostgreSQLContainer extends PostgreSQLContainer { + public NoParamsUrlPostgreSQLContainer() { + super(PostgreSQLTestImages.POSTGRES_TEST_IMAGE); + } @Override public String getJdbcUrl() { diff --git a/modules/postgresql/src/test/java/org/testcontainers/containers/PostgreSQLR2DBCDatabaseContainerTest.java b/modules/postgresql/src/test/java/org/testcontainers/containers/PostgreSQLR2DBCDatabaseContainerTest.java index 505b37859ba..46e439aaf66 100644 --- a/modules/postgresql/src/test/java/org/testcontainers/containers/PostgreSQLR2DBCDatabaseContainerTest.java +++ b/modules/postgresql/src/test/java/org/testcontainers/containers/PostgreSQLR2DBCDatabaseContainerTest.java @@ -1,13 +1,14 @@ package org.testcontainers.containers; import io.r2dbc.spi.ConnectionFactoryOptions; +import org.testcontainers.PostgreSQLTestImages; import org.testcontainers.r2dbc.AbstractR2DBCDatabaseContainerTest; public class PostgreSQLR2DBCDatabaseContainerTest extends AbstractR2DBCDatabaseContainerTest> { @Override protected PostgreSQLContainer createContainer() { - return new PostgreSQLContainer<>(); + return new PostgreSQLContainer<>(PostgreSQLTestImages.POSTGRES_TEST_IMAGE); } @Override diff --git a/modules/postgresql/src/test/java/org/testcontainers/junit/postgresql/CustomizablePostgreSQLTest.java b/modules/postgresql/src/test/java/org/testcontainers/junit/postgresql/CustomizablePostgreSQLTest.java index 8446440059e..8fd523434dd 100644 --- a/modules/postgresql/src/test/java/org/testcontainers/junit/postgresql/CustomizablePostgreSQLTest.java +++ b/modules/postgresql/src/test/java/org/testcontainers/junit/postgresql/CustomizablePostgreSQLTest.java @@ -1,6 +1,7 @@ package org.testcontainers.junit.postgresql; import org.junit.Test; +import org.testcontainers.PostgreSQLTestImages; import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.db.AbstractContainerDatabaseTest; @@ -19,7 +20,7 @@ public class CustomizablePostgreSQLTest extends AbstractContainerDatabaseTest { @Test public void testSimple() throws SQLException { - try (PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:9.6.8") + try (PostgreSQLContainer postgres = new PostgreSQLContainer<>(PostgreSQLTestImages.POSTGRES_TEST_IMAGE) .withDatabaseName(DB_NAME) .withUsername(USER) .withPassword(PWD)) { diff --git a/modules/postgresql/src/test/java/org/testcontainers/junit/postgresql/SimplePostgreSQLTest.java b/modules/postgresql/src/test/java/org/testcontainers/junit/postgresql/SimplePostgreSQLTest.java index 36ece03b604..95e1fdf10fd 100644 --- a/modules/postgresql/src/test/java/org/testcontainers/junit/postgresql/SimplePostgreSQLTest.java +++ b/modules/postgresql/src/test/java/org/testcontainers/junit/postgresql/SimplePostgreSQLTest.java @@ -13,6 +13,7 @@ import static org.junit.Assert.assertThat; import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; import static org.rnorth.visibleassertions.VisibleAssertions.assertNotEquals; +import static org.testcontainers.PostgreSQLTestImages.POSTGRES_TEST_IMAGE; public class SimplePostgreSQLTest extends AbstractContainerDatabaseTest { @@ -23,7 +24,7 @@ public class SimplePostgreSQLTest extends AbstractContainerDatabaseTest { @Test public void testSimple() throws SQLException { - try (PostgreSQLContainer postgres = new PostgreSQLContainer<>()) { + try (PostgreSQLContainer postgres = new PostgreSQLContainer<>(POSTGRES_TEST_IMAGE)) { postgres.start(); ResultSet resultSet = performQuery(postgres, "SELECT 1"); @@ -34,7 +35,7 @@ public void testSimple() throws SQLException { @Test public void testCommandOverride() throws SQLException { - try (PostgreSQLContainer postgres = new PostgreSQLContainer<>().withCommand("postgres -c max_connections=42")) { + try (PostgreSQLContainer postgres = new PostgreSQLContainer<>(POSTGRES_TEST_IMAGE).withCommand("postgres -c max_connections=42")) { postgres.start(); ResultSet resultSet = performQuery(postgres, "SELECT current_setting('max_connections')"); @@ -45,7 +46,7 @@ public void testCommandOverride() throws SQLException { @Test public void testUnsetCommand() throws SQLException { - try (PostgreSQLContainer postgres = new PostgreSQLContainer<>().withCommand("postgres -c max_connections=42").withCommand()) { + try (PostgreSQLContainer postgres = new PostgreSQLContainer<>(POSTGRES_TEST_IMAGE).withCommand("postgres -c max_connections=42").withCommand()) { postgres.start(); ResultSet resultSet = performQuery(postgres, "SELECT current_setting('max_connections')"); @@ -56,7 +57,7 @@ public void testUnsetCommand() throws SQLException { @Test public void testExplicitInitScript() throws SQLException { - try (PostgreSQLContainer postgres = new PostgreSQLContainer<>().withInitScript("somepath/init_postgresql.sql")) { + try (PostgreSQLContainer postgres = new PostgreSQLContainer<>(POSTGRES_TEST_IMAGE).withInitScript("somepath/init_postgresql.sql")) { postgres.start(); ResultSet resultSet = performQuery(postgres, "SELECT foo FROM bar"); @@ -68,7 +69,7 @@ public void testExplicitInitScript() throws SQLException { @Test public void testWithAdditionalUrlParamInJdbcUrl() { - try (PostgreSQLContainer postgres = new PostgreSQLContainer<>() + try (PostgreSQLContainer postgres = new PostgreSQLContainer<>(POSTGRES_TEST_IMAGE) .withUrlParam("charSet", "UNICODE")) { postgres.start(); diff --git a/modules/presto/src/main/java/org/testcontainers/containers/PrestoContainer.java b/modules/presto/src/main/java/org/testcontainers/containers/PrestoContainer.java index c3f25c40ac8..1c8c03ce4de 100644 --- a/modules/presto/src/main/java/org/testcontainers/containers/PrestoContainer.java +++ b/modules/presto/src/main/java/org/testcontainers/containers/PrestoContainer.java @@ -2,6 +2,7 @@ import org.jetbrains.annotations.NotNull; import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; +import org.testcontainers.utility.DockerImageName; import java.sql.Connection; import java.sql.SQLException; @@ -23,11 +24,23 @@ public class PrestoContainer> extends JdbcDat private String username = "test"; private String catalog = null; + /** + * @deprecated use {@link PrestoContainer(DockerImageName)} instead + */ + @Deprecated public PrestoContainer() { this(IMAGE + ":" + DEFAULT_TAG); } + /** + * @deprecated use {@link PrestoContainer(DockerImageName)} instead + */ + @Deprecated public PrestoContainer(final String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public PrestoContainer(final DockerImageName dockerImageName) { super(dockerImageName); this.waitStrategy = new LogMessageWaitStrategy() .withRegEx(".*======== SERVER STARTED ========.*") diff --git a/modules/presto/src/main/java/org/testcontainers/containers/PrestoContainerProvider.java b/modules/presto/src/main/java/org/testcontainers/containers/PrestoContainerProvider.java index 663cf9be4a9..8408aab4517 100644 --- a/modules/presto/src/main/java/org/testcontainers/containers/PrestoContainerProvider.java +++ b/modules/presto/src/main/java/org/testcontainers/containers/PrestoContainerProvider.java @@ -1,8 +1,7 @@ package org.testcontainers.containers; import org.testcontainers.jdbc.ConnectionUrl; - -import java.util.Objects; +import org.testcontainers.utility.DockerImageName; /** * Factory for Presto containers. @@ -24,7 +23,7 @@ public JdbcDatabaseContainer newInstance() { @Override public JdbcDatabaseContainer newInstance(String tag) { - return new PrestoContainer(PrestoContainer.IMAGE + ":" + tag); + return new PrestoContainer(DockerImageName.parse(PrestoContainer.IMAGE).withTag(tag)); } @Override diff --git a/modules/presto/src/test/java/org/testcontainers/PrestoTestImages.java b/modules/presto/src/test/java/org/testcontainers/PrestoTestImages.java new file mode 100644 index 00000000000..1b4e449c99f --- /dev/null +++ b/modules/presto/src/test/java/org/testcontainers/PrestoTestImages.java @@ -0,0 +1,8 @@ +package org.testcontainers; + +import org.testcontainers.utility.DockerImageName; + +public interface PrestoTestImages { + DockerImageName PRESTO_TEST_IMAGE = DockerImageName.parse("prestosql/presto:329"); + DockerImageName PRESTO_PREVIOUS_VERSION_TEST_IMAGE = DockerImageName.parse("prestosql/presto:328"); +} diff --git a/modules/presto/src/test/java/org/testcontainers/containers/PrestoContainerTest.java b/modules/presto/src/test/java/org/testcontainers/containers/PrestoContainerTest.java index 07fb6fa30ed..d5a4d9587a6 100644 --- a/modules/presto/src/test/java/org/testcontainers/containers/PrestoContainerTest.java +++ b/modules/presto/src/test/java/org/testcontainers/containers/PrestoContainerTest.java @@ -2,6 +2,8 @@ import org.junit.Assert; import org.junit.Test; +import org.testcontainers.PrestoTestImages; +import org.testcontainers.utility.DockerImageName; import java.sql.Connection; import java.sql.DriverManager; @@ -22,9 +24,10 @@ * @author findepi */ public class PrestoContainerTest { + @Test public void testSimple() throws Exception { - try (PrestoContainer prestoSql = new PrestoContainer<>()) { + try (PrestoContainer prestoSql = new PrestoContainer<>(PrestoTestImages.PRESTO_TEST_IMAGE)) { prestoSql.start(); try (Connection connection = prestoSql.createConnection(); Statement statement = connection.createStatement(); @@ -37,21 +40,20 @@ public void testSimple() throws Exception { @Test public void testSpecificVersion() throws Exception { - String prestoVersion = Integer.toString(parseInt(PrestoContainer.DEFAULT_TAG) - 1); - try (PrestoContainer prestoSql = new PrestoContainer<>("prestosql/presto:" + prestoVersion)) { + try (PrestoContainer prestoSql = new PrestoContainer<>(PrestoTestImages.PRESTO_PREVIOUS_VERSION_TEST_IMAGE)) { prestoSql.start(); try (Connection connection = prestoSql.createConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT DISTINCT node_version FROM system.runtime.nodes")) { assertTrue("No result", resultSet.next()); - assertEquals("Presto version", prestoVersion, resultSet.getString("node_version")); + assertEquals("Presto version", PrestoTestImages.PRESTO_PREVIOUS_VERSION_TEST_IMAGE.getVersionPart(), resultSet.getString("node_version")); } } } @Test public void testQueryMemoryAndTpch() throws SQLException { - try (PrestoContainer prestoSql = new PrestoContainer<>()) { + try (PrestoContainer prestoSql = new PrestoContainer<>(PrestoTestImages.PRESTO_TEST_IMAGE)) { prestoSql.start(); try (Connection connection = prestoSql.createConnection(); Statement statement = connection.createStatement()) { @@ -77,7 +79,7 @@ public void testQueryMemoryAndTpch() throws SQLException { @Test public void testInitScript() throws Exception { - try (PrestoContainer prestoSql = new PrestoContainer<>()) { + try (PrestoContainer prestoSql = new PrestoContainer<>(PrestoTestImages.PRESTO_TEST_IMAGE)) { prestoSql.withInitScript("initial.sql"); prestoSql.start(); try (Connection connection = prestoSql.createConnection(); diff --git a/modules/pulsar/src/main/java/org/testcontainers/containers/PulsarContainer.java b/modules/pulsar/src/main/java/org/testcontainers/containers/PulsarContainer.java index 936759efb1a..4d30d947113 100644 --- a/modules/pulsar/src/main/java/org/testcontainers/containers/PulsarContainer.java +++ b/modules/pulsar/src/main/java/org/testcontainers/containers/PulsarContainer.java @@ -2,6 +2,7 @@ import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.containers.wait.strategy.WaitAllStrategy; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.TestcontainersConfiguration; /** @@ -13,16 +14,29 @@ public class PulsarContainer extends GenericContainer { public static final int BROKER_HTTP_PORT = 8080; public static final String METRICS_ENDPOINT = "/metrics"; - private static final String PULSAR_VERSION = "2.2.0"; + @Deprecated + private static final String DEFAULT_PULSAR_VERSION = "2.2.0"; private boolean functionsWorkerEnabled = false; + /** + * @deprecated use {@link PulsarContainer(DockerImageName)} instead + */ + @Deprecated public PulsarContainer() { - this(PULSAR_VERSION); + this(DEFAULT_PULSAR_VERSION); } + /** + * @deprecated use {@link PulsarContainer(DockerImageName)} instead + */ + @Deprecated public PulsarContainer(String pulsarVersion) { - super(TestcontainersConfiguration.getInstance().getPulsarImage() + ":" + pulsarVersion); + this(TestcontainersConfiguration.getInstance().getPulsarDockerImageName().withTag(pulsarVersion)); + } + + public PulsarContainer(final DockerImageName dockerImageName) { + super(dockerImageName); withExposedPorts(BROKER_PORT, BROKER_HTTP_PORT); withCommand("/pulsar/bin/pulsar", "standalone", "--no-functions-worker", "-nss"); waitingFor(Wait.forHttp(METRICS_ENDPOINT).forStatusCode(200).forPort(BROKER_HTTP_PORT)); diff --git a/modules/pulsar/src/test/java/org/testcontainers/containers/PulsarContainerTest.java b/modules/pulsar/src/test/java/org/testcontainers/containers/PulsarContainerTest.java index e9d41516670..f2354d98ef7 100644 --- a/modules/pulsar/src/test/java/org/testcontainers/containers/PulsarContainerTest.java +++ b/modules/pulsar/src/test/java/org/testcontainers/containers/PulsarContainerTest.java @@ -7,6 +7,7 @@ import org.apache.pulsar.client.api.Producer; import org.apache.pulsar.client.api.PulsarClient; import org.junit.Test; +import org.testcontainers.utility.DockerImageName; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @@ -17,10 +18,11 @@ public class PulsarContainerTest { public static final String TEST_TOPIC = "test_topic"; + private static final DockerImageName PULSAR_IMAGE = DockerImageName.parse("apachepulsar/pulsar:2.2.0"); @Test public void testUsage() throws Exception { - try (PulsarContainer pulsar = new PulsarContainer()) { + try (PulsarContainer pulsar = new PulsarContainer(PULSAR_IMAGE)) { pulsar.start(); testPulsarFunctionality(pulsar.getPulsarBrokerUrl()); } diff --git a/modules/rabbitmq/src/main/java/org/testcontainers/containers/RabbitMQContainer.java b/modules/rabbitmq/src/main/java/org/testcontainers/containers/RabbitMQContainer.java index d8d46f51b1c..a3b6134b29c 100644 --- a/modules/rabbitmq/src/main/java/org/testcontainers/containers/RabbitMQContainer.java +++ b/modules/rabbitmq/src/main/java/org/testcontainers/containers/RabbitMQContainer.java @@ -5,6 +5,7 @@ import com.github.dockerjava.api.command.InspectContainerResponse; import org.jetbrains.annotations.NotNull; import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.MountableFile; import java.io.IOException; @@ -41,7 +42,9 @@ public class RabbitMQContainer extends GenericContainer { /** * Creates a Testcontainer using the official RabbitMQ docker image. + * @deprecated use {@link RabbitMQContainer(DockerImageName)} instead */ + @Deprecated public RabbitMQContainer() { this(DEFAULT_IMAGE_NAME + ":" + DEFAULT_TAG); } @@ -49,10 +52,16 @@ public RabbitMQContainer() { /** * Creates a Testcontainer using a specific docker image. * - * @param image The docker image to use. + * @param dockerImageName The docker image to use. + * @deprecated use {@link RabbitMQContainer(DockerImageName)} instead */ - public RabbitMQContainer(String image) { - super(image); + @Deprecated + public RabbitMQContainer(String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public RabbitMQContainer(final DockerImageName dockerImageName) { + super(dockerImageName); addExposedPorts(DEFAULT_AMQP_PORT, DEFAULT_AMQPS_PORT, DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT); diff --git a/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQContainerJUnitIntegrationTest.java b/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQContainerJUnitIntegrationTest.java index ff71db44348..7473f470f6f 100644 --- a/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQContainerJUnitIntegrationTest.java +++ b/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQContainerJUnitIntegrationTest.java @@ -13,7 +13,7 @@ public class RabbitMQContainerJUnitIntegrationTest { @ClassRule - public static RabbitMQContainer rabbitMQContainer = new RabbitMQContainer(); + public static RabbitMQContainer rabbitMQContainer = new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE); @Test public void shouldStart() { diff --git a/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQContainerTest.java b/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQContainerTest.java index 4c2787bf5ab..8be97deb710 100644 --- a/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQContainerTest.java +++ b/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQContainerTest.java @@ -1,15 +1,16 @@ package org.testcontainers.containers; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.testcontainers.containers.RabbitMQContainer.SslVerification.VERIFY_PEER; -import static org.testcontainers.utility.MountableFile.forClasspathResource; - import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; +import org.junit.Test; +import org.testcontainers.utility.MountableFile; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -20,18 +21,17 @@ import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.util.Collections; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; -import org.junit.Test; -import org.testcontainers.utility.MountableFile; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.testcontainers.containers.RabbitMQContainer.SslVerification.VERIFY_PEER; +import static org.testcontainers.utility.MountableFile.forClasspathResource; /** * @author Martin Greber */ public class RabbitMQContainerTest { - public static final String DEFAULT_IMAGE = "rabbitmq:3.7.25-management-alpine"; public static final int DEFAULT_AMQPS_PORT = 5671; public static final int DEFAULT_AMQP_PORT = 5672; public static final int DEFAULT_HTTPS_PORT = 15671; @@ -40,9 +40,8 @@ public class RabbitMQContainerTest { @Test public void shouldCreateRabbitMQContainer() { - try (RabbitMQContainer container = new RabbitMQContainer()) { + try (RabbitMQContainer container = new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE)) { - assertThat(container.getDockerImageName()).isEqualTo(DEFAULT_IMAGE); assertThat(container.getAdminPassword()).isEqualTo("guest"); assertThat(container.getAdminUsername()).isEqualTo("guest"); @@ -71,18 +70,10 @@ public void shouldCreateRabbitMQContainer() } } - @Test - public void shouldCreateRabbitMQContainerWithTag() - { - try (RabbitMQContainer container = new RabbitMQContainer(DEFAULT_IMAGE)) { - assertThat(container.getDockerImageName()).isEqualTo(DEFAULT_IMAGE); - } - } - @Test public void shouldCreateRabbitMQContainerWithExchange() throws IOException, InterruptedException { - try (RabbitMQContainer container = new RabbitMQContainer()) { + try (RabbitMQContainer container = new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE)) { container.withExchange("test-exchange", "direct"); container.start(); @@ -95,7 +86,7 @@ public void shouldCreateRabbitMQContainerWithExchange() throws IOException, Inte @Test public void shouldCreateRabbitMQContainerWithExchangeInVhost() throws IOException, InterruptedException { - try (RabbitMQContainer container = new RabbitMQContainer()) { + try (RabbitMQContainer container = new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE)) { container.withVhost("test-vhost"); container.withExchange("test-vhost", "test-exchange", "direct", false, false, false, Collections.emptyMap()); @@ -109,7 +100,7 @@ public void shouldCreateRabbitMQContainerWithExchangeInVhost() throws IOExceptio @Test public void shouldCreateRabbitMQContainerWithQueues() throws IOException, InterruptedException { - try (RabbitMQContainer container = new RabbitMQContainer()) { + try (RabbitMQContainer container = new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE)) { container.withQueue("queue-one") .withQueue("queue-two", false, true, ImmutableMap.of("x-message-ttl", 1000)); @@ -126,7 +117,7 @@ public void shouldCreateRabbitMQContainerWithQueues() throws IOException, Interr @Test public void shouldMountConfigurationFile() { - try (RabbitMQContainer container = new RabbitMQContainer()) { + try (RabbitMQContainer container = new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE)) { container.withRabbitMQConfig(MountableFile.forClasspathResource("/rabbitmq-custom.conf")); container.start(); @@ -140,7 +131,7 @@ public void shouldMountConfigurationFile() @Test public void shouldMountConfigurationFileErlang() { - try (RabbitMQContainer container = new RabbitMQContainer()) { + try (RabbitMQContainer container = new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE)) { container.withRabbitMQConfigErlang(MountableFile.forClasspathResource("/rabbitmq-custom.config")); container.start(); @@ -154,7 +145,7 @@ public void shouldMountConfigurationFileErlang() @Test public void shouldMountConfigurationFileSysctl() { - try (RabbitMQContainer container = new RabbitMQContainer()) { + try (RabbitMQContainer container = new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE)) { container.withRabbitMQConfigSysctl(MountableFile.forClasspathResource("/rabbitmq-custom.conf")); container.start(); @@ -167,7 +158,7 @@ public void shouldMountConfigurationFileSysctl() @Test public void shouldStartTheWholeEnchilada() throws IOException, InterruptedException { - try (RabbitMQContainer container = new RabbitMQContainer()) { + try (RabbitMQContainer container = new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE)) { container .withVhost("vhost1") .withVhostLimit("vhost1", "max-connections", 1) @@ -229,7 +220,7 @@ public void shouldStartTheWholeEnchilada() throws IOException, InterruptedExcept @Test public void shouldThrowExceptionForDodgyJson() { - try (RabbitMQContainer container = new RabbitMQContainer()) { + try (RabbitMQContainer container = new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE)) { assertThatCode(() -> container.withQueue( @@ -245,7 +236,7 @@ public void shouldThrowExceptionForDodgyJson() @Test public void shouldWorkWithSSL() { - try (RabbitMQContainer container = new RabbitMQContainer()) { + try (RabbitMQContainer container = new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE)) { container.withSSL( forClasspathResource("/certs/server_key.pem", 0644), forClasspathResource("/certs/server_certificate.pem", 0644), diff --git a/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQTestImages.java b/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQTestImages.java new file mode 100644 index 00000000000..0898cbdb350 --- /dev/null +++ b/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQTestImages.java @@ -0,0 +1,7 @@ +package org.testcontainers.containers; + +import org.testcontainers.utility.DockerImageName; + +public interface RabbitMQTestImages { + DockerImageName RABBITMQ_IMAGE = DockerImageName.parse("rabbitmq:3.7.25-management-alpine"); +} diff --git a/modules/selenium/src/main/java/org/testcontainers/containers/BrowserWebDriverContainer.java b/modules/selenium/src/main/java/org/testcontainers/containers/BrowserWebDriverContainer.java index 16127171c59..f1cedab76ad 100644 --- a/modules/selenium/src/main/java/org/testcontainers/containers/BrowserWebDriverContainer.java +++ b/modules/selenium/src/main/java/org/testcontainers/containers/BrowserWebDriverContainer.java @@ -1,12 +1,10 @@ package org.testcontainers.containers; +import com.github.dockerjava.api.command.InspectContainerResponse; import com.github.dockerjava.api.model.AccessMode; import com.github.dockerjava.api.model.Bind; import com.github.dockerjava.api.model.Volume; import com.google.common.collect.ImmutableSet; - -import com.github.dockerjava.api.command.InspectContainerResponse; - import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.openqa.selenium.Capabilities; @@ -25,6 +23,7 @@ import org.testcontainers.containers.wait.strategy.WaitStrategy; import org.testcontainers.lifecycle.TestDescription; import org.testcontainers.lifecycle.TestLifecycleAware; +import org.testcontainers.utility.DockerImageName; import java.io.File; import java.io.IOException; @@ -70,8 +69,10 @@ public class BrowserWebDriverContainer() + public NginxContainer nginx = new NginxContainer<>(SeleniumTestImages.NGINX_TEST_IMAGE) .withNetwork(network) .withNetworkAliases("nginx") .withCustomContent(contentFolder.toString()); @Rule - public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer<>() + public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer<>() .withNetwork(network) .withCapabilities(new ChromeOptions()); diff --git a/modules/selenium/src/test/java/org/testcontainers/junit/Selenium3xTest.java b/modules/selenium/src/test/java/org/testcontainers/junit/Selenium3xTest.java index f7415471bc8..bbcd8c15166 100644 --- a/modules/selenium/src/test/java/org/testcontainers/junit/Selenium3xTest.java +++ b/modules/selenium/src/test/java/org/testcontainers/junit/Selenium3xTest.java @@ -5,6 +5,7 @@ import org.junit.runners.Parameterized; import org.openqa.selenium.chrome.ChromeOptions; import org.testcontainers.containers.BrowserWebDriverContainer; +import org.testcontainers.utility.DockerImageName; /** * Simple test to check that readiness detection works correctly across major versions of the containers. @@ -22,7 +23,8 @@ public static String[] data() { @Test public void testAdditionalStartupString() { - try (BrowserWebDriverContainer chrome = new BrowserWebDriverContainer("selenium/standalone-chrome-debug:" + tag) + final DockerImageName imageName = DockerImageName.parse("selenium/standalone-chrome-debug").withTag(tag); + try (BrowserWebDriverContainer chrome = new BrowserWebDriverContainer<>(imageName) .withCapabilities(new ChromeOptions())) { chrome.start(); } diff --git a/modules/selenium/src/test/java/org/testcontainers/junit/SpecificImageNameWebDriverContainerTest.java b/modules/selenium/src/test/java/org/testcontainers/junit/SpecificImageNameWebDriverContainerTest.java index 01edd70c102..6ecf0899ede 100644 --- a/modules/selenium/src/test/java/org/testcontainers/junit/SpecificImageNameWebDriverContainerTest.java +++ b/modules/selenium/src/test/java/org/testcontainers/junit/SpecificImageNameWebDriverContainerTest.java @@ -4,14 +4,14 @@ import org.junit.Test; import org.openqa.selenium.firefox.FirefoxOptions; import org.testcontainers.containers.BrowserWebDriverContainer; +import org.testcontainers.utility.DockerImageName; -/** - * - */ public class SpecificImageNameWebDriverContainerTest extends BaseWebDriverContainerTest { + private static final DockerImageName FIREFOX_IMAGE = DockerImageName.parse("selenium/standalone-firefox:2.53.1-beryllium"); + @Rule - public BrowserWebDriverContainer firefox = new BrowserWebDriverContainer("selenium/standalone-firefox:2.53.1-beryllium") + public BrowserWebDriverContainer firefox = new BrowserWebDriverContainer<>(FIREFOX_IMAGE) .withCapabilities(new FirefoxOptions()); @Test diff --git a/modules/solr/src/main/java/org/testcontainers/containers/SolrContainer.java b/modules/solr/src/main/java/org/testcontainers/containers/SolrContainer.java index 90fd674dfda..aeadb664089 100644 --- a/modules/solr/src/main/java/org/testcontainers/containers/SolrContainer.java +++ b/modules/solr/src/main/java/org/testcontainers/containers/SolrContainer.java @@ -1,18 +1,17 @@ package org.testcontainers.containers; -import static java.time.temporal.ChronoUnit.SECONDS; +import com.github.dockerjava.api.command.InspectContainerResponse; +import lombok.SneakyThrows; +import org.apache.commons.lang.StringUtils; +import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; +import org.testcontainers.utility.DockerImageName; import java.net.URL; import java.time.Duration; import java.util.HashSet; import java.util.Set; -import com.github.dockerjava.api.command.InspectContainerResponse; - -import lombok.SneakyThrows; - -import org.apache.commons.lang.StringUtils; -import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; +import static java.time.temporal.ChronoUnit.SECONDS; /** * SolrContainer allows a solr container to be launched and controlled. @@ -27,11 +26,23 @@ public class SolrContainer extends GenericContainer { private SolrContainerConfiguration configuration; + /** + * @deprecated use {@link SolrContainer(DockerImageName)} instead + */ + @Deprecated public SolrContainer() { this(IMAGE + ":" + DEFAULT_TAG); } + /** + * @deprecated use {@link SolrContainer(DockerImageName)} instead + */ + @Deprecated public SolrContainer(final String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public SolrContainer(final DockerImageName dockerImageName) { super(dockerImageName); this.waitStrategy = new LogMessageWaitStrategy() .withRegEx(".*o\\.e\\.j\\.s\\.Server Started.*") diff --git a/modules/solr/src/test/java/org/testcontainers/containers/SolrContainerTest.java b/modules/solr/src/test/java/org/testcontainers/containers/SolrContainerTest.java index 48cb04b7053..c2d19a3e61c 100644 --- a/modules/solr/src/test/java/org/testcontainers/containers/SolrContainerTest.java +++ b/modules/solr/src/test/java/org/testcontainers/containers/SolrContainerTest.java @@ -1,23 +1,25 @@ package org.testcontainers.containers; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -import java.io.IOException; - import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.Http2SolrClient; import org.apache.solr.client.solrj.response.SolrPingResponse; import org.junit.After; import org.junit.Test; +import org.testcontainers.utility.DockerImageName; + +import java.io.IOException; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; /** * @author Simon Schneider */ public class SolrContainerTest { + private static final DockerImageName SOLR_IMAGE = DockerImageName.parse("solr:8.3.0"); private SolrClient client = null; @After @@ -30,7 +32,7 @@ public void stopRestClient() throws IOException { @Test public void solrCloudTest() throws IOException, SolrServerException { - try (SolrContainer container = new SolrContainer()) { + try (SolrContainer container = new SolrContainer(SOLR_IMAGE)) { container.start(); SolrPingResponse response = getClient(container).ping("dummy"); assertThat(response.getStatus(), is(0)); @@ -40,7 +42,7 @@ public void solrCloudTest() throws IOException, SolrServerException { @Test public void solrStandaloneTest() throws IOException, SolrServerException { - try (SolrContainer container = new SolrContainer().withZookeeper(false)) { + try (SolrContainer container = new SolrContainer(SOLR_IMAGE).withZookeeper(false)) { container.start(); SolrPingResponse response = getClient(container).ping("dummy"); assertThat(response.getStatus(), is(0)); @@ -52,7 +54,7 @@ public void solrStandaloneTest() throws IOException, SolrServerException { public void solrCloudPingTest() throws IOException, SolrServerException { // solrContainerUsage { // Create the solr container. - SolrContainer container = new SolrContainer(); + SolrContainer container = new SolrContainer(SOLR_IMAGE); // Start the container. This step might take some time... container.start(); diff --git a/modules/spock/src/test/groovy/org/testcontainers/spock/MySqlContainerIT.groovy b/modules/spock/src/test/groovy/org/testcontainers/spock/MySqlContainerIT.groovy index 7a68302289f..639b46f5886 100644 --- a/modules/spock/src/test/groovy/org/testcontainers/spock/MySqlContainerIT.groovy +++ b/modules/spock/src/test/groovy/org/testcontainers/spock/MySqlContainerIT.groovy @@ -15,7 +15,7 @@ import spock.lang.Specification class MySqlContainerIT extends Specification { @Shared - MySQLContainer mySQLContainer = new MySQLContainer() + MySQLContainer mySQLContainer = new MySQLContainer(SpockTestImages.MYSQL_IMAGE) def "dummy test"() { expect: diff --git a/modules/spock/src/test/groovy/org/testcontainers/spock/PostgresContainerIT.groovy b/modules/spock/src/test/groovy/org/testcontainers/spock/PostgresContainerIT.groovy index 4ac095bed6f..a886d552732 100644 --- a/modules/spock/src/test/groovy/org/testcontainers/spock/PostgresContainerIT.groovy +++ b/modules/spock/src/test/groovy/org/testcontainers/spock/PostgresContainerIT.groovy @@ -14,7 +14,7 @@ import java.sql.Statement class PostgresContainerIT extends Specification { @Shared - PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer() + PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer(SpockTestImages.POSTGRES_TEST_IMAGE) .withDatabaseName("foo") .withUsername("foo") .withPassword("secret") diff --git a/modules/spock/src/test/groovy/org/testcontainers/spock/SpockTestImages.groovy b/modules/spock/src/test/groovy/org/testcontainers/spock/SpockTestImages.groovy new file mode 100644 index 00000000000..526c1fe5c42 --- /dev/null +++ b/modules/spock/src/test/groovy/org/testcontainers/spock/SpockTestImages.groovy @@ -0,0 +1,11 @@ +package org.testcontainers.spock; + +import org.testcontainers.utility.DockerImageName +import org.testcontainers.utility.TestcontainersConfiguration; + +interface SpockTestImages { + DockerImageName MYSQL_IMAGE = DockerImageName.parse("mysql:5.7.22") + DockerImageName POSTGRES_TEST_IMAGE = DockerImageName.parse("postgres:9.6.12") + DockerImageName HTTPD_IMAGE = DockerImageName.parse("httpd:2.4-alpine") + DockerImageName TINY_IMAGE = TestcontainersConfiguration.getInstance().getTinyDockerImageName() +} diff --git a/modules/spock/src/test/groovy/org/testcontainers/spock/TestHierarchyIT.groovy b/modules/spock/src/test/groovy/org/testcontainers/spock/TestHierarchyIT.groovy index 123828327bc..7fb37446ca5 100644 --- a/modules/spock/src/test/groovy/org/testcontainers/spock/TestHierarchyIT.groovy +++ b/modules/spock/src/test/groovy/org/testcontainers/spock/TestHierarchyIT.groovy @@ -10,7 +10,7 @@ import spock.lang.Shared class TestHierarchyIT extends MySqlContainerIT { @Shared - PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer() + PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer(SpockTestImages.POSTGRES_TEST_IMAGE) .withDatabaseName("foo") .withUsername("foo") .withPassword("secret") diff --git a/modules/spock/src/test/groovy/org/testcontainers/spock/TestLifecycleAwareContainerMock.java b/modules/spock/src/test/groovy/org/testcontainers/spock/TestLifecycleAwareContainerMock.java index 43be6d32ca4..eb628fd2f33 100644 --- a/modules/spock/src/test/groovy/org/testcontainers/spock/TestLifecycleAwareContainerMock.java +++ b/modules/spock/src/test/groovy/org/testcontainers/spock/TestLifecycleAwareContainerMock.java @@ -8,6 +8,8 @@ import java.util.List; import java.util.Optional; +import static org.testcontainers.spock.SpockTestImages.TINY_IMAGE; + public class TestLifecycleAwareContainerMock extends GenericContainer implements TestLifecycleAware { static final String BEFORE_TEST = "beforeTest"; @@ -18,6 +20,10 @@ public class TestLifecycleAwareContainerMock extends GenericContainer { private final Map proxies = new HashMap<>(); private final AtomicInteger nextPort = new AtomicInteger(FIRST_PROXIED_PORT); + /** + * @deprecated use {@link ToxiproxyContainer(DockerImageName)} instead + */ + @Deprecated public ToxiproxyContainer() { this(IMAGE_NAME); } - public ToxiproxyContainer(String imageName) { - super(imageName); + /** + * @deprecated use {@link ToxiproxyContainer(DockerImageName)} instead + */ + @Deprecated + public ToxiproxyContainer(String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public ToxiproxyContainer(final DockerImageName dockerImageName) { + super(dockerImageName); addExposedPorts(TOXIPROXY_CONTROL_PORT); setWaitStrategy(new HttpWaitStrategy().forPath("/version").forPort(TOXIPROXY_CONTROL_PORT)); diff --git a/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java b/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java index d76851f57b5..87f9758ebf1 100644 --- a/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java +++ b/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java @@ -1,16 +1,19 @@ package org.testcontainers.containers; import eu.rekawek.toxiproxy.model.ToxicDirection; -import java.time.Duration; import org.junit.Rule; import org.junit.Test; +import org.testcontainers.utility.DockerImageName; import redis.clients.jedis.Jedis; import redis.clients.jedis.exceptions.JedisConnectionException; import java.io.IOException; +import java.time.Duration; import static java.lang.String.format; -import static org.rnorth.visibleassertions.VisibleAssertions.*; +import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.rnorth.visibleassertions.VisibleAssertions.assertThrows; +import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; public class ToxiproxyTest { @@ -25,15 +28,17 @@ public class ToxiproxyTest { @Rule public Network network = Network.newNetwork(); + private static final DockerImageName REDIS_IMAGE = DockerImageName.parse("redis:5.0.4"); // The target container - this could be anything @Rule - public GenericContainer redis = new GenericContainer("redis:5.0.4") + public GenericContainer redis = new GenericContainer<>(REDIS_IMAGE) .withExposedPorts(6379) .withNetwork(network); + private static final DockerImageName TOXIPROXY_IMAGE = DockerImageName.parse("shopify/toxiproxy:2.1.0"); // Toxiproxy container, which will be used as a TCP proxy @Rule - public ToxiproxyContainer toxiproxy = new ToxiproxyContainer() + public ToxiproxyContainer toxiproxy = new ToxiproxyContainer(TOXIPROXY_IMAGE) .withNetwork(network) .withNetworkAliases(TOXIPROXY_NETWORK_ALIAS); // } @@ -99,7 +104,7 @@ public void testConnectionCut() { @Test public void testMultipleProxiesCanBeCreated() { - try (GenericContainer secondRedis = new GenericContainer("redis:5.0.4") + try (GenericContainer secondRedis = new GenericContainer<>(REDIS_IMAGE) .withExposedPorts(6379) .withNetwork(network)) { diff --git a/modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java b/modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java index ac4e730adb3..1532f463f37 100644 --- a/modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java +++ b/modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java @@ -3,6 +3,7 @@ import com.github.dockerjava.api.command.InspectContainerResponse; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; import java.io.IOException; import java.util.ArrayList; @@ -28,11 +29,23 @@ public class VaultContainer> extends GenericCo private int port = VAULT_PORT; + /** + * @deprecated use {@link VaultContainer(DockerImageName)} instead + */ + @Deprecated public VaultContainer() { this("vault:1.1.3"); } + /** + * @deprecated use {@link VaultContainer(DockerImageName)} instead + */ + @Deprecated public VaultContainer(String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public VaultContainer(final DockerImageName dockerImageName) { super(dockerImageName); // Use the vault healthcheck endpoint to check for readiness, per https://www.vaultproject.io/api/system/health.html diff --git a/modules/vault/src/test/java/org/testcontainers/vault/VaultClientTest.java b/modules/vault/src/test/java/org/testcontainers/vault/VaultClientTest.java index dfe73cae4b9..4a1a800da17 100644 --- a/modules/vault/src/test/java/org/testcontainers/vault/VaultClientTest.java +++ b/modules/vault/src/test/java/org/testcontainers/vault/VaultClientTest.java @@ -10,6 +10,7 @@ import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; +import static org.testcontainers.vault.VaultTestImages.VAULT_IMAGE; public class VaultClientTest { @@ -18,7 +19,7 @@ public class VaultClientTest { @Test public void writeAndReadMultipleValues() throws VaultException { try ( - VaultContainer vaultContainer = new VaultContainer<>() + VaultContainer vaultContainer = new VaultContainer<>(VAULT_IMAGE) .withVaultToken(VAULT_TOKEN) ) { diff --git a/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java b/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java index d7ac5ca8686..b3dd788f053 100644 --- a/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java +++ b/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java @@ -19,7 +19,7 @@ public class VaultContainerTest { private static final String VAULT_TOKEN = "my-root-token"; @ClassRule - public static VaultContainer vaultContainer = new VaultContainer<>() + public static VaultContainer vaultContainer = new VaultContainer<>(VaultTestImages.VAULT_IMAGE) .withVaultToken(VAULT_TOKEN) .withSecretInVault("secret/testing1", "top_secret=password123") .withSecretInVault("secret/testing2", diff --git a/modules/vault/src/test/java/org/testcontainers/vault/VaultTestImages.java b/modules/vault/src/test/java/org/testcontainers/vault/VaultTestImages.java new file mode 100644 index 00000000000..9afecdcffb9 --- /dev/null +++ b/modules/vault/src/test/java/org/testcontainers/vault/VaultTestImages.java @@ -0,0 +1,7 @@ +package org.testcontainers.vault; + +import org.testcontainers.utility.DockerImageName; + +public interface VaultTestImages { + DockerImageName VAULT_IMAGE = DockerImageName.parse("vault:1.1.3"); +}