diff --git a/core/build.gradle b/core/build.gradle index 4dad6c61131..2131b5e423b 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -69,7 +69,6 @@ configurations.all { } dependencies { - api 'junit:junit:4.13.2' api 'org.slf4j:slf4j-api:1.7.36' compileOnly 'org.jetbrains:annotations:24.1.0' testCompileOnly 'org.jetbrains:annotations:24.1.0' @@ -106,6 +105,8 @@ dependencies { shaded 'org.zeroturnaround:zt-exec:1.12' + testImplementation project(":junit4") + testImplementation 'junit:junit:4.13.2' testImplementation('com.google.cloud.tools:jib-core:0.23.0') { exclude group: 'com.google.guava', module: 'guava' } diff --git a/core/src/main/java/org/testcontainers/containers/ComposeContainer.java b/core/src/main/java/org/testcontainers/containers/ComposeContainer.java index 79d706d3b6a..e8061363a18 100644 --- a/core/src/main/java/org/testcontainers/containers/ComposeContainer.java +++ b/core/src/main/java/org/testcontainers/containers/ComposeContainer.java @@ -5,8 +5,6 @@ import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.SystemUtils; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; import org.testcontainers.containers.output.OutputFrame; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.containers.wait.strategy.WaitStrategy; @@ -31,7 +29,7 @@ * It uses either Compose V2 contained within the Docker binary, or a containerised version of Compose V2. */ @Slf4j -public class ComposeContainer extends FailureDetectingExternalResource implements Startable { +public class ComposeContainer implements Startable { private final Map scalingPreferences = new HashMap<>(); @@ -93,32 +91,6 @@ public ComposeContainer(String identifier, List composeFiles) { this.project = this.composeDelegate.getProject(); } - @Override - @Deprecated - public Statement apply(Statement base, Description description) { - return super.apply(base, description); - } - - @Override - @Deprecated - public void starting(Description description) { - start(); - } - - @Override - @Deprecated - protected void succeeded(Description description) {} - - @Override - @Deprecated - protected void failed(Throwable e, Description description) {} - - @Override - @Deprecated - public void finished(Description description) { - stop(); - } - @Override public void start() { synchronized (MUTEX) { diff --git a/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java b/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java index 92dc75b6cde..dd06b181b42 100644 --- a/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java +++ b/core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java @@ -5,8 +5,6 @@ import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.SystemUtils; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; import org.testcontainers.containers.output.OutputFrame; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.containers.wait.strategy.WaitStrategy; @@ -30,9 +28,7 @@ * Container which launches Docker Compose, for the purposes of launching a defined set of containers. */ @Slf4j -public class DockerComposeContainer> - extends FailureDetectingExternalResource - implements Startable { +public class DockerComposeContainer> implements Startable { private final Map scalingPreferences = new HashMap<>(); @@ -99,32 +95,6 @@ public DockerComposeContainer(String identifier, List composeFiles) { this.project = this.composeDelegate.getProject(); } - @Override - @Deprecated - public Statement apply(Statement base, Description description) { - return super.apply(base, description); - } - - @Override - @Deprecated - public void starting(Description description) { - start(); - } - - @Override - @Deprecated - protected void succeeded(Description description) {} - - @Override - @Deprecated - protected void failed(Throwable e, Description description) {} - - @Override - @Deprecated - public void finished(Description description) { - stop(); - } - @Override public void start() { synchronized (MUTEX) { diff --git a/core/src/main/java/org/testcontainers/containers/FailureDetectingExternalResource.java b/core/src/main/java/org/testcontainers/containers/FailureDetectingExternalResource.java deleted file mode 100644 index 71344267d32..00000000000 --- a/core/src/main/java/org/testcontainers/containers/FailureDetectingExternalResource.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.testcontainers.containers; - -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.MultipleFailureException; -import org.junit.runners.model.Statement; - -import java.util.ArrayList; -import java.util.List; - -/** - * {@link TestRule} which is called before and after each test, and also is notified on success/failure. - * - * This mimics the behaviour of TestWatcher to some degree, but failures occurring in this rule do not - * contribute to the overall failure count (which can otherwise cause strange negative test success - * figures). - */ -public class FailureDetectingExternalResource implements TestRule { - - @Override - public Statement apply(Statement base, Description description) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - List errors = new ArrayList(); - - try { - starting(description); - base.evaluate(); - succeeded(description); - } catch (Throwable e) { - errors.add(e); - failed(e, description); - } finally { - finished(description); - } - - MultipleFailureException.assertEmpty(errors); - } - }; - } - - protected void starting(Description description) {} - - protected void succeeded(Description description) {} - - protected void failed(Throwable e, Description description) {} - - protected void finished(Description description) {} -} diff --git a/core/src/main/java/org/testcontainers/containers/GenericContainer.java b/core/src/main/java/org/testcontainers/containers/GenericContainer.java index acd70f69cab..0fe944433ae 100644 --- a/core/src/main/java/org/testcontainers/containers/GenericContainer.java +++ b/core/src/main/java/org/testcontainers/containers/GenericContainer.java @@ -32,8 +32,6 @@ import org.apache.commons.lang3.SystemUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; import org.rnorth.ducttape.unreliables.Unreliables; import org.slf4j.Logger; import org.testcontainers.DockerClientFactory; @@ -52,8 +50,6 @@ import org.testcontainers.images.builder.Transferable; import org.testcontainers.lifecycle.Startable; import org.testcontainers.lifecycle.Startables; -import org.testcontainers.lifecycle.TestDescription; -import org.testcontainers.lifecycle.TestLifecycleAware; import org.testcontainers.utility.Base58; import org.testcontainers.utility.CommandLine; import org.testcontainers.utility.DockerImageName; @@ -106,7 +102,6 @@ */ @Data public class GenericContainer> - extends FailureDetectingExternalResource implements Container, AutoCloseable, WaitStrategyTarget, Startable { public static final int CONTAINER_RUNNING_TIMEOUT_SEC = 30; @@ -1053,57 +1048,6 @@ public void addExposedPorts(int... ports) { this.containerDef.addExposedTcpPorts(ports); } - private TestDescription toDescription(Description description) { - return new TestDescription() { - @Override - public String getTestId() { - return description.getDisplayName(); - } - - @Override - public String getFilesystemFriendlyName() { - return description.getClassName() + "-" + description.getMethodName(); - } - }; - } - - @Override - @Deprecated - public Statement apply(Statement base, Description description) { - return super.apply(base, description); - } - - @Override - @Deprecated - protected void starting(Description description) { - if (this instanceof TestLifecycleAware) { - ((TestLifecycleAware) this).beforeTest(toDescription(description)); - } - this.start(); - } - - @Override - @Deprecated - protected void succeeded(Description description) { - if (this instanceof TestLifecycleAware) { - ((TestLifecycleAware) this).afterTest(toDescription(description), Optional.empty()); - } - } - - @Override - @Deprecated - protected void failed(Throwable e, Description description) { - if (this instanceof TestLifecycleAware) { - ((TestLifecycleAware) this).afterTest(toDescription(description), Optional.of(e)); - } - } - - @Override - @Deprecated - protected void finished(Description description) { - this.stop(); - } - /** * {@inheritDoc} */ diff --git a/core/src/main/java/org/testcontainers/containers/Network.java b/core/src/main/java/org/testcontainers/containers/Network.java index 88ddd6dd906..27cab80c652 100644 --- a/core/src/main/java/org/testcontainers/containers/Network.java +++ b/core/src/main/java/org/testcontainers/containers/Network.java @@ -4,8 +4,6 @@ import lombok.Builder; import lombok.Getter; import lombok.Singular; -import org.junit.rules.ExternalResource; -import org.junit.rules.TestRule; import org.testcontainers.DockerClientFactory; import org.testcontainers.utility.ResourceReaper; @@ -17,7 +15,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; -public interface Network extends AutoCloseable, TestRule { +public interface Network extends AutoCloseable { Network SHARED = new NetworkImpl(false, null, Collections.emptySet(), null) { @Override public void close() { @@ -40,7 +38,7 @@ static NetworkImpl.NetworkImplBuilder builder() { @Builder @Getter - class NetworkImpl extends ExternalResource implements Network { + class NetworkImpl implements Network { private final String name = UUID.randomUUID().toString(); @@ -100,11 +98,6 @@ private String create() { return createNetworkCmd.exec().getId(); } - @Override - protected void after() { - close(); - } - @Override public synchronized void close() { if (initialized.getAndSet(false)) { diff --git a/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java b/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java index 4ce316fcf80..e368372b246 100644 --- a/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java +++ b/core/src/test/java/org/testcontainers/containers/ExposedHostTest.java @@ -7,8 +7,6 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; import org.testcontainers.DockerClientFactory; import org.testcontainers.TestImages; import org.testcontainers.Testcontainers; @@ -189,11 +187,6 @@ public String getId() { @Override public void close() {} - - @Override - public Statement apply(Statement base, Description description) { - return null; - } }; List networks = DockerClientFactory diff --git a/core/src/test/java/org/testcontainers/containers/FailureDetectingExternalResourceTest.java b/core/src/test/java/org/testcontainers/containers/FailureDetectingExternalResourceTest.java deleted file mode 100644 index c743fcf6a43..00000000000 --- a/core/src/test/java/org/testcontainers/containers/FailureDetectingExternalResourceTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.testcontainers.containers; - -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; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -public class FailureDetectingExternalResourceTest { - - @Test - public void finishedIsCalledForCleanupIfStartingThrows() throws Throwable { - FailureDetectingExternalResource res = spy(FailureDetectingExternalResource.class); - Statement stmt = res.apply(mock(Statement.class), Description.EMPTY); - doThrow(new RuntimeException()).when(res).starting(any()); - try { - stmt.evaluate(); - } catch (Throwable t) { - // ignore - } - verify(res).starting(any()); - verify(res).finished(any()); - } -} diff --git a/core/src/test/java/org/testcontainers/containers/NetworkTest.java b/core/src/test/java/org/testcontainers/containers/NetworkTest.java index 099bef20ed7..141af293cca 100644 --- a/core/src/test/java/org/testcontainers/containers/NetworkTest.java +++ b/core/src/test/java/org/testcontainers/containers/NetworkTest.java @@ -6,6 +6,7 @@ import org.junit.runner.RunWith; import org.testcontainers.DockerClientFactory; import org.testcontainers.TestImages; +import org.testcontainers.junit4.TestcontainersRule; import static org.assertj.core.api.Assertions.assertThat; @@ -15,22 +16,24 @@ public class NetworkTest { public static class WithRules { @Rule - public Network network = Network.newNetwork(); + public TestcontainersRule network = new TestcontainersRule<>(Network.newNetwork()); @Rule - 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"); + public TestcontainersRule> foo = new TestcontainersRule<>( + new GenericContainer<>(TestImages.TINY_IMAGE) + .withNetwork(network.get()) + .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<>(TestImages.TINY_IMAGE) - .withNetwork(network) - .withCommand("top"); + public TestcontainersRule> bar = new TestcontainersRule<>( + new GenericContainer<>(TestImages.TINY_IMAGE).withNetwork(network.get()).withCommand("top") + ); @Test public void testNetworkSupport() throws Exception { - String response = bar.execInContainer("wget", "-O", "-", "http://foo:8080").getStdout(); + String response = bar.get().execInContainer("wget", "-O", "-", "http://foo:8080").getStdout(); assertThat(response).as("received response").isEqualTo("yay"); } } diff --git a/core/src/test/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheckTest.java b/core/src/test/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheckTest.java index d93eb90c339..9a0f58f4ceb 100644 --- a/core/src/test/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheckTest.java +++ b/core/src/test/java/org/testcontainers/containers/wait/internal/InternalCommandPortListeningCheckTest.java @@ -9,6 +9,7 @@ import org.rnorth.ducttape.unreliables.Unreliables; import org.testcontainers.containers.GenericContainer; import org.testcontainers.images.builder.ImageFromDockerfile; +import org.testcontainers.junit4.TestcontainersRule; import java.util.Arrays; import java.util.concurrent.TimeUnit; @@ -30,21 +31,23 @@ public static Iterable data() { } @Rule - public GenericContainer container; + public TestcontainersRule> container; public InternalCommandPortListeningCheckTest(String dockerfile) { container = - new GenericContainer( - new ImageFromDockerfile() - .withFileFromClasspath("Dockerfile", dockerfile) - .withFileFromClasspath("nginx.conf", "internal-port-check-dockerfile/nginx.conf") + new TestcontainersRule<>( + new GenericContainer( + new ImageFromDockerfile() + .withFileFromClasspath("Dockerfile", dockerfile) + .withFileFromClasspath("nginx.conf", "internal-port-check-dockerfile/nginx.conf") + ) ); } @Test public void singleListening() { final InternalCommandPortListeningCheck check = new InternalCommandPortListeningCheck( - container, + container.get(), ImmutableSet.of(8080) ); @@ -54,7 +57,7 @@ public void singleListening() { @Test public void nonListening() { final InternalCommandPortListeningCheck check = new InternalCommandPortListeningCheck( - container, + container.get(), ImmutableSet.of(8080, 1234) ); @@ -67,7 +70,7 @@ public void nonListening() { @Test public void lowAndHighPortListening() { final InternalCommandPortListeningCheck check = new InternalCommandPortListeningCheck( - container, + container.get(), ImmutableSet.of(100, 8080) ); diff --git a/core/src/test/java/org/testcontainers/images/ImagePullPolicyTest.java b/core/src/test/java/org/testcontainers/images/ImagePullPolicyTest.java index a885c035e5c..10a0c9a9596 100644 --- a/core/src/test/java/org/testcontainers/images/ImagePullPolicyTest.java +++ b/core/src/test/java/org/testcontainers/images/ImagePullPolicyTest.java @@ -9,6 +9,7 @@ import org.testcontainers.containers.ContainerLaunchException; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import static org.assertj.core.api.Assertions.fail; @@ -17,9 +18,11 @@ public class ImagePullPolicyTest { @ClassRule - public static DockerRegistryContainer registry = new DockerRegistryContainer(); + public static TestcontainersRule registry = new TestcontainersRule<>( + new DockerRegistryContainer() + ); - private final DockerImageName imageName = registry.createImage(); + private final DockerImageName imageName = registry.get().createImage(); @Test public void pullsByDefault() { diff --git a/core/src/test/java/org/testcontainers/junit/ComposeContainerPortViaEnvTest.java b/core/src/test/java/org/testcontainers/junit/ComposeContainerPortViaEnvTest.java index b27f4b080da..145872f83ef 100644 --- a/core/src/test/java/org/testcontainers/junit/ComposeContainerPortViaEnvTest.java +++ b/core/src/test/java/org/testcontainers/junit/ComposeContainerPortViaEnvTest.java @@ -2,20 +2,21 @@ import org.junit.Rule; import org.testcontainers.containers.ComposeContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.io.File; public class ComposeContainerPortViaEnvTest extends BaseComposeTest { @Rule - public ComposeContainer environment = new ComposeContainer( - new File("src/test/resources/v2-compose-test-port-via-env.yml") - ) - .withExposedService("redis-1", REDIS_PORT) - .withEnv("REDIS_PORT", String.valueOf(REDIS_PORT)); + public TestcontainersRule environment = new TestcontainersRule<>( + new ComposeContainer(new File("src/test/resources/v2-compose-test-port-via-env.yml")) + .withExposedService("redis-1", REDIS_PORT) + .withEnv("REDIS_PORT", String.valueOf(REDIS_PORT)) + ); @Override protected ComposeContainer getEnvironment() { - return environment; + return environment.get(); } } diff --git a/core/src/test/java/org/testcontainers/junit/ComposeContainerTest.java b/core/src/test/java/org/testcontainers/junit/ComposeContainerTest.java index 39c7ff2baf5..4acfb58807e 100644 --- a/core/src/test/java/org/testcontainers/junit/ComposeContainerTest.java +++ b/core/src/test/java/org/testcontainers/junit/ComposeContainerTest.java @@ -5,6 +5,7 @@ import org.testcontainers.containers.ComposeContainer; import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.io.File; import java.io.IOException; @@ -19,30 +20,30 @@ public class ComposeContainerTest extends BaseComposeTest { @Rule // composeContainerConstructor { - public ComposeContainer environment = new ComposeContainer( - new File("src/test/resources/composev2/compose-test.yml") - ) - .withExposedService("redis-1", REDIS_PORT) - .withExposedService("db-1", 3306); + public TestcontainersRule environment = new TestcontainersRule<>( + new ComposeContainer(new File("src/test/resources/composev2/compose-test.yml")) + .withExposedService("redis-1", REDIS_PORT) + .withExposedService("db-1", 3306) + ); // } @Override protected ComposeContainer getEnvironment() { - return environment; + return environment.get(); } @Test public void testGetServiceHostAndPort() { // getServiceHostAndPort { - String serviceHost = environment.getServiceHost("redis-1", REDIS_PORT); - int serviceWithInstancePort = environment.getServicePort("redis-1", REDIS_PORT); + String serviceHost = environment.get().getServiceHost("redis-1", REDIS_PORT); + int serviceWithInstancePort = environment.get().getServicePort("redis-1", REDIS_PORT); // } assertThat(serviceHost).as("Service host is not blank").isNotBlank(); assertThat(serviceWithInstancePort).as("Port is set for service with instance number").isNotNull(); - int serviceWithoutInstancePort = environment.getServicePort("redis", REDIS_PORT); + int serviceWithoutInstancePort = environment.get().getServicePort("redis", REDIS_PORT); assertThat(serviceWithoutInstancePort).as("Port is set for service with instance number").isNotNull(); assertThat(serviceWithoutInstancePort).as("Service ports are the same").isEqualTo(serviceWithInstancePort); } @@ -50,7 +51,7 @@ public void testGetServiceHostAndPort() { @Test public void shouldRetrieveContainerByServiceName() { String existingServiceName = "db-1"; - Optional result = environment.getContainerByServiceName(existingServiceName); + Optional result = environment.get().getContainerByServiceName(existingServiceName); assertThat(result) .as(String.format("Container should be found by service name %s", existingServiceName)) .isPresent(); @@ -62,7 +63,7 @@ public void shouldRetrieveContainerByServiceName() { @Test public void shouldReturnEmptyResultOnNoneExistingService() { String notExistingServiceName = "db-256"; - Optional result = environment.getContainerByServiceName(notExistingServiceName); + Optional result = environment.get().getContainerByServiceName(notExistingServiceName); assertThat(result) .as(String.format("No container should be found under service name %s", notExistingServiceName)) .isNotPresent(); diff --git a/core/src/test/java/org/testcontainers/junit/ComposePassthroughTest.java b/core/src/test/java/org/testcontainers/junit/ComposePassthroughTest.java index d1724cb1e70..fef898013ba 100644 --- a/core/src/test/java/org/testcontainers/junit/ComposePassthroughTest.java +++ b/core/src/test/java/org/testcontainers/junit/ComposePassthroughTest.java @@ -7,6 +7,7 @@ import org.testcontainers.containers.ComposeContainer; import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.TestEnvironment; import java.io.File; @@ -25,11 +26,11 @@ public static void checkVersion() { } @Rule - public ComposeContainer compose = new ComposeContainer( - new File("src/test/resources/v2-compose-test-passthrough.yml") - ) - .withEnv("foo", "bar") - .withExposedService("alpine-1", 3000, waitStrategy); + public TestcontainersRule compose = new TestcontainersRule<>( + new ComposeContainer(new File("src/test/resources/v2-compose-test-passthrough.yml")) + .withEnv("foo", "bar") + .withExposedService("alpine-1", 3000, waitStrategy) + ); @Test public void testContainerInstanceProperties() { diff --git a/core/src/test/java/org/testcontainers/junit/ComposeWaitStrategyTest.java b/core/src/test/java/org/testcontainers/junit/ComposeWaitStrategyTest.java index a77f80d227e..aad95630928 100644 --- a/core/src/test/java/org/testcontainers/junit/ComposeWaitStrategyTest.java +++ b/core/src/test/java/org/testcontainers/junit/ComposeWaitStrategyTest.java @@ -3,7 +3,6 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.junit.runner.Description; import org.mockito.Mockito; import org.testcontainers.containers.ComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; @@ -37,7 +36,7 @@ public void testWaitOnListeningPort() { environment.withExposedService("redis-1", REDIS_PORT, Wait.forListeningPort()); try { - environment.starting(Description.createTestDescription(Object.class, "name")); + environment.start(); } catch (RuntimeException e) { fail("Docker compose should start after waiting for listening port with failed with: " + e); } @@ -51,7 +50,7 @@ public void testWaitOnMultipleStrategiesPassing() { .withTailChildContainers(true); try { - environment.starting(Description.createTestDescription(Object.class, "name")); + environment.start(); } catch (RuntimeException e) { fail("Docker compose should start after waiting for listening port with failed with: " + e); } @@ -64,7 +63,7 @@ public void testWaitingFails() { REDIS_PORT, Wait.forHttp("/test").withStartupTimeout(Duration.ofSeconds(10)) ); - assertThat(catchThrowable(() -> environment.starting(Description.createTestDescription(Object.class, "name")))) + assertThat(catchThrowable(() -> environment.start())) .as("waiting on an invalid http path times out") .isInstanceOf(RuntimeException.class); } @@ -83,7 +82,7 @@ public void testWaitOnOneOfMultipleStrategiesFailing() { ) .withTailChildContainers(true); - assertThat(catchThrowable(() -> environment.starting(Description.createTestDescription(Object.class, "name")))) + assertThat(catchThrowable(() -> environment.start())) .as("waiting on one failing strategy to time out") .isInstanceOf(RuntimeException.class); } diff --git a/core/src/test/java/org/testcontainers/junit/ComposeWithIdentifierTest.java b/core/src/test/java/org/testcontainers/junit/ComposeWithIdentifierTest.java index f94449bb39f..54346cf4b6e 100644 --- a/core/src/test/java/org/testcontainers/junit/ComposeWithIdentifierTest.java +++ b/core/src/test/java/org/testcontainers/junit/ComposeWithIdentifierTest.java @@ -2,20 +2,20 @@ import org.junit.Rule; import org.testcontainers.containers.ComposeContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.io.File; public class ComposeWithIdentifierTest extends BaseComposeTest { @Rule - public ComposeContainer environment = new ComposeContainer( - "TEST", - new File("src/test/resources/v2-compose-test.yml") - ) - .withExposedService("redis-1", REDIS_PORT); + public TestcontainersRule environment = new TestcontainersRule<>( + new ComposeContainer("TEST", new File("src/test/resources/v2-compose-test.yml")) + .withExposedService("redis-1", REDIS_PORT) + ); @Override protected ComposeContainer getEnvironment() { - return this.environment; + return this.environment.get(); } } diff --git a/core/src/test/java/org/testcontainers/junit/ComposeWithNetworkTest.java b/core/src/test/java/org/testcontainers/junit/ComposeWithNetworkTest.java index 3ce63b2a5fe..b09f7b5df50 100644 --- a/core/src/test/java/org/testcontainers/junit/ComposeWithNetworkTest.java +++ b/core/src/test/java/org/testcontainers/junit/ComposeWithNetworkTest.java @@ -2,19 +2,20 @@ import org.junit.Rule; import org.testcontainers.containers.ComposeContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.io.File; public class ComposeWithNetworkTest extends BaseComposeTest { @Rule - public ComposeContainer environment = new ComposeContainer( - new File("src/test/resources/v2-compose-test-with-network.yml") - ) - .withExposedService("redis-1", REDIS_PORT); + public TestcontainersRule environment = new TestcontainersRule<>( + new ComposeContainer(new File("src/test/resources/v2-compose-test-with-network.yml")) + .withExposedService("redis-1", REDIS_PORT) + ); @Override protected ComposeContainer getEnvironment() { - return environment; + return environment.get(); } } diff --git a/core/src/test/java/org/testcontainers/junit/DockerComposeContainerPortViaEnvTest.java b/core/src/test/java/org/testcontainers/junit/DockerComposeContainerPortViaEnvTest.java index 849e2a8e6a6..07207da2e23 100644 --- a/core/src/test/java/org/testcontainers/junit/DockerComposeContainerPortViaEnvTest.java +++ b/core/src/test/java/org/testcontainers/junit/DockerComposeContainerPortViaEnvTest.java @@ -2,20 +2,21 @@ import org.junit.Rule; import org.testcontainers.containers.DockerComposeContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.io.File; public class DockerComposeContainerPortViaEnvTest extends BaseDockerComposeTest { @Rule - public DockerComposeContainer environment = new DockerComposeContainer( - new File("src/test/resources/v2-compose-test-port-via-env.yml") - ) - .withExposedService("redis_1", REDIS_PORT) - .withEnv("REDIS_PORT", String.valueOf(REDIS_PORT)); + public TestcontainersRule environment = new TestcontainersRule<>( + new DockerComposeContainer(new File("src/test/resources/v2-compose-test-port-via-env.yml")) + .withExposedService("redis_1", REDIS_PORT) + .withEnv("REDIS_PORT", String.valueOf(REDIS_PORT)) + ); @Override protected DockerComposeContainer getEnvironment() { - return environment; + return environment.get(); } } diff --git a/core/src/test/java/org/testcontainers/junit/DockerComposeContainerScalingTest.java b/core/src/test/java/org/testcontainers/junit/DockerComposeContainerScalingTest.java index 5571e42dcf7..658b864e003 100644 --- a/core/src/test/java/org/testcontainers/junit/DockerComposeContainerScalingTest.java +++ b/core/src/test/java/org/testcontainers/junit/DockerComposeContainerScalingTest.java @@ -6,6 +6,7 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.DockerComposeContainer; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.TestEnvironment; import redis.clients.jedis.Jedis; @@ -28,13 +29,13 @@ public static void checkVersion() { } @Rule - public DockerComposeContainer environment = new DockerComposeContainer( - new File("src/test/resources/scaled-compose-test.yml") - ) - .withScaledService("redis", 3) - .withExposedService("redis", REDIS_PORT) // implicit '_1' - .withExposedService("redis_2", REDIS_PORT) // explicit service index - .withExposedService("redis", 3, REDIS_PORT); // explicit service index via parameter + public TestcontainersRule environment = new TestcontainersRule<>( + new DockerComposeContainer(new File("src/test/resources/scaled-compose-test.yml")) + .withScaledService("redis", 3) + .withExposedService("redis", REDIS_PORT) // implicit '_1' + .withExposedService("redis_2", REDIS_PORT) // explicit service index + .withExposedService("redis", 3, REDIS_PORT) // explicit service index via parameter + ); @Before public void setupClients() { @@ -42,7 +43,10 @@ public void setupClients() { String name = String.format("redis_%d", i + 1); clients[i] = - new Jedis(environment.getServiceHost(name, REDIS_PORT), environment.getServicePort(name, REDIS_PORT)); + new Jedis( + environment.get().getServiceHost(name, REDIS_PORT), + environment.get().getServicePort(name, REDIS_PORT) + ); } } diff --git a/core/src/test/java/org/testcontainers/junit/DockerComposeContainerTest.java b/core/src/test/java/org/testcontainers/junit/DockerComposeContainerTest.java index 96989af90a4..05fa8cae09e 100644 --- a/core/src/test/java/org/testcontainers/junit/DockerComposeContainerTest.java +++ b/core/src/test/java/org/testcontainers/junit/DockerComposeContainerTest.java @@ -4,6 +4,7 @@ import org.junit.Test; import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.io.File; import java.io.IOException; @@ -20,22 +21,22 @@ public class DockerComposeContainerTest extends BaseDockerComposeTest { @Rule - public DockerComposeContainer environment = new DockerComposeContainer( - new File("src/test/resources/compose-test.yml") - ) - .withExposedService("redis_1", REDIS_PORT) - .withExposedService("db_1", 3306); + public TestcontainersRule environment = new TestcontainersRule<>( + new DockerComposeContainer(new File("src/test/resources/compose-test.yml")) + .withExposedService("redis_1", REDIS_PORT) + .withExposedService("db_1", 3306) + ); @Override protected DockerComposeContainer getEnvironment() { - return environment; + return environment.get(); } @Test public void testGetServicePort() { - int serviceWithInstancePort = environment.getServicePort("redis_1", REDIS_PORT); + int serviceWithInstancePort = environment.get().getServicePort("redis_1", REDIS_PORT); assertThat(serviceWithInstancePort).as("Port is set for service with instance number").isNotNull(); - int serviceWithoutInstancePort = environment.getServicePort("redis", REDIS_PORT); + int serviceWithoutInstancePort = environment.get().getServicePort("redis", REDIS_PORT); assertThat(serviceWithoutInstancePort).as("Port is set for service with instance number").isNotNull(); assertThat(serviceWithoutInstancePort).as("Service ports are the same").isEqualTo(serviceWithInstancePort); } @@ -43,7 +44,7 @@ public void testGetServicePort() { @Test public void shouldRetrieveContainerByServiceName() { String existingServiceName = "db_1"; - Optional result = environment.getContainerByServiceName(existingServiceName); + Optional result = environment.get().getContainerByServiceName(existingServiceName); assertThat(result) .as(String.format("Container should be found by service name %s", existingServiceName)) @@ -56,7 +57,7 @@ public void shouldRetrieveContainerByServiceName() { @Test public void shouldRetrieveContainerByServiceNameWithoutNumberedSuffix() { String existingServiceName = "db"; - Optional result = environment.getContainerByServiceName(existingServiceName); + Optional result = environment.get().getContainerByServiceName(existingServiceName); assertThat(result) .as(String.format("Container should be found by service name %s", existingServiceName)) @@ -69,7 +70,7 @@ public void shouldRetrieveContainerByServiceNameWithoutNumberedSuffix() { @Test public void shouldReturnEmptyResultOnNoneExistingService() { String notExistingServiceName = "db_256"; - Optional result = environment.getContainerByServiceName(notExistingServiceName); + Optional result = environment.get().getContainerByServiceName(notExistingServiceName); assertThat(result) .as(String.format("No container should be found under service name %s", notExistingServiceName)) .isNotPresent(); diff --git a/core/src/test/java/org/testcontainers/junit/DockerComposeLogConsumerTest.java b/core/src/test/java/org/testcontainers/junit/DockerComposeLogConsumerTest.java index 97e686a9b92..c8df6769aef 100644 --- a/core/src/test/java/org/testcontainers/junit/DockerComposeLogConsumerTest.java +++ b/core/src/test/java/org/testcontainers/junit/DockerComposeLogConsumerTest.java @@ -1,7 +1,6 @@ package org.testcontainers.junit; import org.junit.Test; -import org.junit.runner.Description; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.output.OutputFrame.OutputType; import org.testcontainers.containers.output.WaitingConsumer; @@ -22,7 +21,7 @@ public void testLogConsumer() throws TimeoutException { .withLogConsumer("redis_1", logConsumer); try { - environment.starting(Description.EMPTY); + environment.start(); logConsumer.waitUntil( frame -> { return ( @@ -34,7 +33,7 @@ public void testLogConsumer() throws TimeoutException { TimeUnit.SECONDS ); } finally { - environment.finished(Description.EMPTY); + environment.close(); } } } diff --git a/core/src/test/java/org/testcontainers/junit/DockerComposePassthroughTest.java b/core/src/test/java/org/testcontainers/junit/DockerComposePassthroughTest.java index 10a26306248..884ff09c169 100644 --- a/core/src/test/java/org/testcontainers/junit/DockerComposePassthroughTest.java +++ b/core/src/test/java/org/testcontainers/junit/DockerComposePassthroughTest.java @@ -7,6 +7,7 @@ import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.TestEnvironment; import java.io.File; @@ -28,11 +29,11 @@ public static void checkVersion() { } @Rule - public DockerComposeContainer compose = new DockerComposeContainer( - new File("src/test/resources/v2-compose-test-passthrough.yml") - ) - .withEnv("foo", "bar") - .withExposedService("alpine_1", 3000, waitStrategy); + public TestcontainersRule compose = new TestcontainersRule<>( + new DockerComposeContainer(new File("src/test/resources/v2-compose-test-passthrough.yml")) + .withEnv("foo", "bar") + .withExposedService("alpine_1", 3000, waitStrategy) + ); @Test public void testContainerInstanceProperties() { diff --git a/core/src/test/java/org/testcontainers/junit/DockerComposeServiceTest.java b/core/src/test/java/org/testcontainers/junit/DockerComposeServiceTest.java index ccca85407f3..8fe97e55b98 100644 --- a/core/src/test/java/org/testcontainers/junit/DockerComposeServiceTest.java +++ b/core/src/test/java/org/testcontainers/junit/DockerComposeServiceTest.java @@ -3,6 +3,7 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.DockerComposeContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.io.File; @@ -11,24 +12,24 @@ public class DockerComposeServiceTest extends BaseDockerComposeTest { @Rule - public DockerComposeContainer environment = new DockerComposeContainer( - new File("src/test/resources/compose-test.yml") - ) - .withServices("redis") - .withExposedService("redis_1", REDIS_PORT); + public TestcontainersRule environment = new TestcontainersRule<>( + new DockerComposeContainer(new File("src/test/resources/compose-test.yml")) + .withServices("redis") + .withExposedService("redis_1", REDIS_PORT) + ); @Override protected DockerComposeContainer getEnvironment() { - return environment; + return environment.get(); } @Test(expected = IllegalArgumentException.class) public void testDbIsNotStarting() { - environment.getServicePort("db_1", 10001); + environment.get().getServicePort("db_1", 10001); } @Test public void testRedisIsStarting() { - assertThat(environment.getServicePort("redis_1", REDIS_PORT)).as("Redis server started").isNotNull(); + assertThat(environment.get().getServicePort("redis_1", REDIS_PORT)).as("Redis server started").isNotNull(); } } diff --git a/core/src/test/java/org/testcontainers/junit/DockerComposeV2FormatTest.java b/core/src/test/java/org/testcontainers/junit/DockerComposeV2FormatTest.java index f3dc2ee3cc8..4ae9a1d24f2 100644 --- a/core/src/test/java/org/testcontainers/junit/DockerComposeV2FormatTest.java +++ b/core/src/test/java/org/testcontainers/junit/DockerComposeV2FormatTest.java @@ -2,6 +2,7 @@ import org.junit.Rule; import org.testcontainers.containers.DockerComposeContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.io.File; @@ -11,13 +12,13 @@ public class DockerComposeV2FormatTest extends BaseDockerComposeTest { @Rule - public DockerComposeContainer environment = new DockerComposeContainer( - new File("src/test/resources/v2-compose-test.yml") - ) - .withExposedService("redis_1", REDIS_PORT); + public TestcontainersRule environment = new TestcontainersRule<>( + new DockerComposeContainer(new File("src/test/resources/v2-compose-test.yml")) + .withExposedService("redis_1", REDIS_PORT) + ); @Override protected DockerComposeContainer getEnvironment() { - return environment; + return environment.get(); } } diff --git a/core/src/test/java/org/testcontainers/junit/DockerComposeV2FormatWithIdentifierTest.java b/core/src/test/java/org/testcontainers/junit/DockerComposeV2FormatWithIdentifierTest.java index 90c041b53b6..1e27c76454e 100644 --- a/core/src/test/java/org/testcontainers/junit/DockerComposeV2FormatWithIdentifierTest.java +++ b/core/src/test/java/org/testcontainers/junit/DockerComposeV2FormatWithIdentifierTest.java @@ -2,20 +2,20 @@ import org.junit.Rule; import org.testcontainers.containers.DockerComposeContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.io.File; public class DockerComposeV2FormatWithIdentifierTest extends BaseDockerComposeTest { @Rule - public DockerComposeContainer environment = new DockerComposeContainer( - "TEST", - new File("src/test/resources/v2-compose-test.yml") - ) - .withExposedService("redis_1", REDIS_PORT); + public TestcontainersRule environment = new TestcontainersRule<>( + new DockerComposeContainer("TEST", new File("src/test/resources/v2-compose-test.yml")) + .withExposedService("redis_1", REDIS_PORT) + ); @Override protected DockerComposeContainer getEnvironment() { - return this.environment; + return environment.get(); } } diff --git a/core/src/test/java/org/testcontainers/junit/DockerComposeV2WithNetworkTest.java b/core/src/test/java/org/testcontainers/junit/DockerComposeV2WithNetworkTest.java index b28dfc3ee51..972377048ea 100644 --- a/core/src/test/java/org/testcontainers/junit/DockerComposeV2WithNetworkTest.java +++ b/core/src/test/java/org/testcontainers/junit/DockerComposeV2WithNetworkTest.java @@ -2,19 +2,20 @@ import org.junit.Rule; import org.testcontainers.containers.DockerComposeContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.io.File; public class DockerComposeV2WithNetworkTest extends BaseDockerComposeTest { @Rule - public DockerComposeContainer environment = new DockerComposeContainer( - new File("src/test/resources/v2-compose-test-with-network.yml") - ) - .withExposedService("redis_1", REDIS_PORT); + public TestcontainersRule environment = new TestcontainersRule<>( + new DockerComposeContainer(new File("src/test/resources/v2-compose-test-with-network.yml")) + .withExposedService("redis_1", REDIS_PORT) + ); @Override protected DockerComposeContainer getEnvironment() { - return environment; + return environment.get(); } } diff --git a/core/src/test/java/org/testcontainers/junit/DockerComposeWaitStrategyTest.java b/core/src/test/java/org/testcontainers/junit/DockerComposeWaitStrategyTest.java index b110e776285..f1e1b9bb0fa 100644 --- a/core/src/test/java/org/testcontainers/junit/DockerComposeWaitStrategyTest.java +++ b/core/src/test/java/org/testcontainers/junit/DockerComposeWaitStrategyTest.java @@ -3,7 +3,6 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.junit.runner.Description; import org.mockito.Mockito; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; @@ -37,7 +36,7 @@ public void testWaitOnListeningPort() { environment.withExposedService("redis_1", REDIS_PORT, Wait.forListeningPort()); try { - environment.starting(Description.createTestDescription(Object.class, "name")); + environment.start(); } catch (RuntimeException e) { fail("Docker compose should start after waiting for listening port with failed with: " + e); } @@ -51,7 +50,7 @@ public void testWaitOnMultipleStrategiesPassing() { .withTailChildContainers(true); try { - environment.starting(Description.createTestDescription(Object.class, "name")); + environment.start(); } catch (RuntimeException e) { fail("Docker compose should start after waiting for listening port with failed with: " + e); } @@ -64,7 +63,7 @@ public void testWaitingFails() { REDIS_PORT, Wait.forHttp("/test").withStartupTimeout(Duration.ofSeconds(10)) ); - assertThat(catchThrowable(() -> environment.starting(Description.createTestDescription(Object.class, "name")))) + assertThat(catchThrowable(() -> environment.start())) .as("waiting on an invalid http path times out") .isInstanceOf(RuntimeException.class); } @@ -83,7 +82,7 @@ public void testWaitOnOneOfMultipleStrategiesFailing() { ) .withTailChildContainers(true); - assertThat(catchThrowable(() -> environment.starting(Description.createTestDescription(Object.class, "name")))) + assertThat(catchThrowable(() -> environment.start())) .as("waiting on one failing strategy to time out") .isInstanceOf(RuntimeException.class); } diff --git a/core/src/test/java/org/testcontainers/junit/DockerfileContainerTest.java b/core/src/test/java/org/testcontainers/junit/DockerfileContainerTest.java index 9ed143aca9c..e51198787ef 100644 --- a/core/src/test/java/org/testcontainers/junit/DockerfileContainerTest.java +++ b/core/src/test/java/org/testcontainers/junit/DockerfileContainerTest.java @@ -8,6 +8,7 @@ import org.junit.Test; import org.testcontainers.containers.GenericContainer; import org.testcontainers.images.builder.ImageFromDockerfile; +import org.testcontainers.junit4.TestcontainersRule; import java.io.IOException; @@ -19,21 +20,27 @@ public class DockerfileContainerTest { @Rule - public GenericContainer dslContainer = new GenericContainer( - new ImageFromDockerfile("tcdockerfile/nginx", false) - .withDockerfileFromBuilder(builder -> { - builder - .from("alpine:3.2") // - .run("apk add --update nginx") - .cmd("nginx", "-g", "daemon off;") - .build(); - }) - ) - .withExposedPorts(80); + public TestcontainersRule> dslContainer = new TestcontainersRule<>( + new GenericContainer( + new ImageFromDockerfile("tcdockerfile/nginx", false) + .withDockerfileFromBuilder(builder -> { + builder + .from("alpine:3.2") // + .run("apk add --update nginx") + .cmd("nginx", "-g", "daemon off;") + .build(); + }) + ) + .withExposedPorts(80) + ); @Test public void simpleDslTest() throws IOException { - String address = String.format("http://%s:%s", dslContainer.getHost(), dslContainer.getMappedPort(80)); + String address = String.format( + "http://%s:%s", + dslContainer.get().getHost(), + dslContainer.get().getMappedPort(80) + ); CloseableHttpClient httpClient = HttpClientBuilder.create().build(); HttpGet get = new HttpGet(address); diff --git a/core/src/test/java/org/testcontainers/junit/ExecInContainerTest.java b/core/src/test/java/org/testcontainers/junit/ExecInContainerTest.java index a3dd21318d2..230dd6e898c 100644 --- a/core/src/test/java/org/testcontainers/junit/ExecInContainerTest.java +++ b/core/src/test/java/org/testcontainers/junit/ExecInContainerTest.java @@ -6,6 +6,7 @@ import org.testcontainers.TestImages; import org.testcontainers.containers.ExecConfig; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.TestEnvironment; import java.util.Collections; @@ -15,7 +16,9 @@ public class ExecInContainerTest { @ClassRule - public static GenericContainer redis = new GenericContainer<>(TestImages.REDIS_IMAGE).withExposedPorts(6379); + public static TestcontainersRule> redis = new TestcontainersRule<>( + new GenericContainer<>(TestImages.REDIS_IMAGE).withExposedPorts(6379) + ); @Test public void shouldExecuteCommand() throws Exception { @@ -24,7 +27,7 @@ public void shouldExecuteCommand() throws Exception { // Once they resolve the issue, this clause can be removed. Assume.assumeTrue(TestEnvironment.dockerExecutionDriverSupportsExec()); - final GenericContainer.ExecResult result = redis.execInContainer("redis-cli", "role"); + final GenericContainer.ExecResult result = redis.get().execInContainer("redis-cli", "role"); assertThat(result.getStdout()) .as("Output for \"redis-cli role\" command should start with \"master\"") .startsWith("master"); @@ -39,7 +42,7 @@ public void shouldExecuteCommandWithUser() throws Exception { // Once they resolve the issue, this clause can be removed. Assume.assumeTrue(TestEnvironment.dockerExecutionDriverSupportsExec()); - final GenericContainer.ExecResult result = redis.execInContainerWithUser("redis", "whoami"); + final GenericContainer.ExecResult result = redis.get().execInContainerWithUser("redis", "whoami"); assertThat(result.getStdout()) .as("Output for \"whoami\" command should start with \"redis\"") .startsWith("redis"); @@ -51,9 +54,9 @@ public void shouldExecuteCommandWithUser() throws Exception { public void shouldExecuteCommandWithWorkdir() throws Exception { Assume.assumeTrue(TestEnvironment.dockerExecutionDriverSupportsExec()); - final GenericContainer.ExecResult result = redis.execInContainer( - ExecConfig.builder().workDir("/opt").command(new String[] { "pwd" }).build() - ); + final GenericContainer.ExecResult result = redis + .get() + .execInContainer(ExecConfig.builder().workDir("/opt").command(new String[] { "pwd" }).build()); assertThat(result.getStdout()).startsWith("/opt"); } @@ -61,13 +64,15 @@ public void shouldExecuteCommandWithWorkdir() throws Exception { public void shouldExecuteCommandWithEnvVars() throws Exception { Assume.assumeTrue(TestEnvironment.dockerExecutionDriverSupportsExec()); - final GenericContainer.ExecResult result = redis.execInContainer( - ExecConfig - .builder() - .envVars(Collections.singletonMap("TESTCONTAINERS", "JAVA")) - .command(new String[] { "env" }) - .build() - ); + final GenericContainer.ExecResult result = redis + .get() + .execInContainer( + ExecConfig + .builder() + .envVars(Collections.singletonMap("TESTCONTAINERS", "JAVA")) + .command(new String[] { "env" }) + .build() + ); assertThat(result.getStdout()).contains("TESTCONTAINERS=JAVA"); } } diff --git a/core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java b/core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java index 5a9d7c1616d..11d3b5b28ad 100644 --- a/core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java +++ b/core/src/test/java/org/testcontainers/junit/GenericContainerRuleTest.java @@ -26,6 +26,7 @@ import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.SelinuxContext; import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.Base58; import java.io.BufferedReader; @@ -79,75 +80,88 @@ public static void setupContent() throws FileNotFoundException { * Redis */ @ClassRule - public static GenericContainer redis = new GenericContainer<>(TestImages.REDIS_IMAGE) - .withExposedPorts(REDIS_PORT); + public static TestcontainersRule> redis = new TestcontainersRule<>( + new GenericContainer<>(TestImages.REDIS_IMAGE).withExposedPorts(REDIS_PORT) + ); /** * RabbitMQ */ @ClassRule - public static GenericContainer rabbitMq = new GenericContainer<>(TestImages.RABBITMQ_IMAGE) - .withExposedPorts(RABBITMQ_PORT); + public static TestcontainersRule> rabbitMq = new TestcontainersRule<>( + new GenericContainer<>(TestImages.RABBITMQ_IMAGE).withExposedPorts(RABBITMQ_PORT) + ); /** * MongoDB */ @ClassRule - public static GenericContainer mongo = new GenericContainer<>(TestImages.MONGODB_IMAGE) - .withExposedPorts(MONGO_PORT); + public static TestcontainersRule> mongo = new TestcontainersRule<>( + new GenericContainer<>(TestImages.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<>(TestImages.ALPINE_IMAGE) - .withExposedPorts(80) - .withEnv("MAGIC_NUMBER", "4") - .withEnv("MAGIC_NUMBER", oldValue -> oldValue.orElse("") + "2") - .withCommand("/bin/sh", "-c", "while true; do echo \"$MAGIC_NUMBER\" | nc -l -p 80; done"); + public static TestcontainersRule> alpineEnvVar = new TestcontainersRule<>( + new GenericContainer<>(TestImages.ALPINE_IMAGE) + .withExposedPorts(80) + .withEnv("MAGIC_NUMBER", "4") + .withEnv("MAGIC_NUMBER", oldValue -> oldValue.orElse("") + "2") + .withCommand("/bin/sh", "-c", "while true; do echo \"$MAGIC_NUMBER\" | nc -l -p 80; done") + ); /** * Pass environment variables to the container, then run a shell script that exposes the variables in a quick and * dirty way for testing. */ @ClassRule - public static GenericContainer alpineEnvVarFromMap = new GenericContainer<>(TestImages.ALPINE_IMAGE) - .withExposedPorts(80) - .withEnv(ImmutableMap.of("FIRST", "42", "SECOND", "50")) - .withCommand("/bin/sh", "-c", "while true; do echo \"$FIRST and $SECOND\" | nc -l -p 80; done"); + public static TestcontainersRule> alpineEnvVarFromMap = new TestcontainersRule<>( + new GenericContainer<>(TestImages.ALPINE_IMAGE) + .withExposedPorts(80) + .withEnv(ImmutableMap.of("FIRST", "42", "SECOND", "50")) + .withCommand("/bin/sh", "-c", "while true; do echo \"$FIRST and $SECOND\" | nc -l -p 80; done") + ); /** * 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<>(TestImages.ALPINE_IMAGE) - .withExposedPorts(80) - .withClasspathResourceMapping("mappable-resource/test-resource.txt", "/content.txt", BindMode.READ_ONLY) - .withCommand("/bin/sh", "-c", "while true; do cat /content.txt | nc -l -p 80; done"); + public static TestcontainersRule> alpineClasspathResource = new TestcontainersRule<>( + new GenericContainer<>(TestImages.ALPINE_IMAGE) + .withExposedPorts(80) + .withClasspathResourceMapping("mappable-resource/test-resource.txt", "/content.txt", BindMode.READ_ONLY) + .withCommand("/bin/sh", "-c", "while true; do cat /content.txt | nc -l -p 80; done") + ); /** * 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<>(TestImages.ALPINE_IMAGE) - .withExposedPorts(80) - .withClasspathResourceMapping( - "mappable-resource/test-resource.txt", - "/content.txt", - BindMode.READ_WRITE, - SelinuxContext.SHARED - ) - .withCommand("/bin/sh", "-c", "while true; do cat /content.txt | nc -l -p 80; done"); + public static TestcontainersRule> alpineClasspathResourceSelinux = new TestcontainersRule<>( + new GenericContainer<>(TestImages.ALPINE_IMAGE) + .withExposedPorts(80) + .withClasspathResourceMapping( + "mappable-resource/test-resource.txt", + "/content.txt", + BindMode.READ_WRITE, + SelinuxContext.SHARED + ) + .withCommand("/bin/sh", "-c", "while true; do cat /content.txt | nc -l -p 80; done") + ); /** * Create a container with an extra host entry and expose the content of /etc/hosts for testing. */ @ClassRule - public static GenericContainer alpineExtrahost = new GenericContainer<>(TestImages.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"); + public static TestcontainersRule> alpineExtrahost = new TestcontainersRule<>( + new GenericContainer<>(TestImages.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() { @@ -182,8 +196,8 @@ public void withTmpFsTest() throws Exception { @Test public void simpleRabbitMqTest() throws IOException, TimeoutException { ConnectionFactory factory = new ConnectionFactory(); - factory.setHost(rabbitMq.getHost()); - factory.setPort(rabbitMq.getMappedPort(RABBITMQ_PORT)); + factory.setHost(rabbitMq.get().getHost()); + factory.setPort(rabbitMq.get().getMappedPort(RABBITMQ_PORT)); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); @@ -231,7 +245,7 @@ public void handleDelivery( @Test public void simpleMongoDbTest() { - MongoClient mongoClient = new MongoClient(mongo.getHost(), mongo.getMappedPort(MONGO_PORT)); + MongoClient mongoClient = new MongoClient(mongo.get().getHost(), mongo.get().getMappedPort(MONGO_PORT)); MongoDatabase database = mongoClient.getDatabase("test"); MongoCollection collection = database.getCollection("testCollection"); @@ -244,14 +258,14 @@ public void simpleMongoDbTest() { @Test public void environmentAndCustomCommandTest() throws IOException { - String line = getReaderForContainerPort80(alpineEnvVar).readLine(); + String line = getReaderForContainerPort80(alpineEnvVar.get()).readLine(); assertThat(line).as("An environment variable can be passed into a command").isEqualTo("42"); } @Test public void environmentFromMapTest() throws IOException { - String line = getReaderForContainerPort80(alpineEnvVarFromMap).readLine(); + String line = getReaderForContainerPort80(alpineEnvVarFromMap.get()).readLine(); assertThat(line).as("Environment variables can be passed into a command from a map").isEqualTo("42 and 50"); } @@ -299,7 +313,7 @@ public void exceptionThrownWhenTryingToOverrideTestcontainersLabels() { public void customClasspathResourceMappingTest() throws IOException { // Note: This functionality doesn't work if you are running your build inside a Docker container; // in that case this test will fail. - String line = getReaderForContainerPort80(alpineClasspathResource).readLine(); + String line = getReaderForContainerPort80(alpineClasspathResource.get()).readLine(); assertThat(line) .as("Resource on the classpath can be mapped using calls to withClasspathResourceMapping") @@ -308,7 +322,7 @@ public void customClasspathResourceMappingTest() throws IOException { @Test public void customClasspathResourceMappingWithSelinuxTest() throws IOException { - String line = getReaderForContainerPort80(alpineClasspathResourceSelinux).readLine(); + String line = getReaderForContainerPort80(alpineClasspathResourceSelinux.get()).readLine(); assertThat(line) .as("Resource on the classpath can be mapped using calls to withClasspathResourceMappingSelinux") .isEqualTo("FOOBAR"); @@ -316,7 +330,7 @@ public void customClasspathResourceMappingWithSelinuxTest() throws IOException { @Test public void exceptionThrownWhenMappedPortNotFound() { - assertThat(catchThrowable(() -> redis.getMappedPort(666))) + assertThat(catchThrowable(() -> redis.get().getMappedPort(666))) .as("When the requested port is not mapped, getMappedPort() throws an exception") .isInstanceOf(IllegalArgumentException.class); } @@ -359,7 +373,7 @@ public void failFastWhenContainerHaltsImmediately() { @Test public void extraHostTest() throws IOException { - BufferedReader br = getReaderForContainerPort80(alpineExtrahost); + BufferedReader br = getReaderForContainerPort80(alpineExtrahost.get()); // read hosts file from container StringBuffer hosts = new StringBuffer(); @@ -411,19 +425,19 @@ private BufferedReader getReaderForContainerPort80(GenericContainer container) { @Test public void addExposedPortAfterWithExposedPortsTest() { - redis.addExposedPort(8987); - assertThat(redis.getExposedPorts()).as("Both ports should be exposed").hasSize(2); - assertThat(redis.getExposedPorts()).as("withExposedPort should be exposed").contains(REDIS_PORT); - assertThat(redis.getExposedPorts()).as("addExposedPort should be exposed").contains(8987); + redis.get().addExposedPort(8987); + assertThat(redis.get().getExposedPorts()).as("Both ports should be exposed").hasSize(2); + assertThat(redis.get().getExposedPorts()).as("withExposedPort should be exposed").contains(REDIS_PORT); + assertThat(redis.get().getExposedPorts()).as("addExposedPort should be exposed").contains(8987); } @Test public void addingExposedPortTwiceShouldNotFail() { - redis.addExposedPort(8987); - redis.addExposedPort(8987); - assertThat(redis.getExposedPorts()).as("Both ports should be exposed").hasSize(2); // 2 ports = de-duplicated port 8897 and original port 6379 - assertThat(redis.getExposedPorts()).as("withExposedPort should be exposed").contains(REDIS_PORT); - assertThat(redis.getExposedPorts()).as("addExposedPort should be exposed").contains(8987); + redis.get().addExposedPort(8987); + redis.get().addExposedPort(8987); + assertThat(redis.get().getExposedPorts()).as("Both ports should be exposed").hasSize(2); // 2 ports = de-duplicated port 8897 and original port 6379 + assertThat(redis.get().getExposedPorts()).as("withExposedPort should be exposed").contains(REDIS_PORT); + assertThat(redis.get().getExposedPorts()).as("addExposedPort should be exposed").contains(8987); } @Test diff --git a/core/src/test/java/org/testcontainers/junit/OutputStreamTest.java b/core/src/test/java/org/testcontainers/junit/OutputStreamTest.java index 17b1d247cbb..087947e35dc 100644 --- a/core/src/test/java/org/testcontainers/junit/OutputStreamTest.java +++ b/core/src/test/java/org/testcontainers/junit/OutputStreamTest.java @@ -10,6 +10,7 @@ import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.containers.output.ToStringConsumer; import org.testcontainers.containers.output.WaitingConsumer; +import org.testcontainers.junit4.TestcontainersRule; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -24,8 +25,9 @@ public class OutputStreamTest { @Rule - public GenericContainer container = new GenericContainer(TestImages.ALPINE_IMAGE) - .withCommand("ping -c 5 127.0.0.1"); + public TestcontainersRule> container = new TestcontainersRule<>( + new GenericContainer(TestImages.ALPINE_IMAGE).withCommand("ping -c 5 127.0.0.1") + ); private static final Logger LOGGER = LoggerFactory.getLogger(OutputStreamTest.class); @@ -33,7 +35,7 @@ public class OutputStreamTest { public void testFetchStdout() throws TimeoutException { WaitingConsumer consumer = new WaitingConsumer(); - container.followOutput(consumer, OutputFrame.OutputType.STDOUT); + container.get().followOutput(consumer, OutputFrame.OutputType.STDOUT); consumer.waitUntil( frame -> frame.getType() == OutputFrame.OutputType.STDOUT && frame.getUtf8String().contains("seq=2"), @@ -46,7 +48,7 @@ public void testFetchStdout() throws TimeoutException { public void testFetchStdoutWithTimeout() { WaitingConsumer consumer = new WaitingConsumer(); - container.followOutput(consumer, OutputFrame.OutputType.STDOUT); + container.get().followOutput(consumer, OutputFrame.OutputType.STDOUT); assertThat( catchThrowable(() -> { @@ -69,7 +71,7 @@ public void testFetchStdoutWithTimeout() { public void testFetchStdoutWithNoLimit() throws TimeoutException { WaitingConsumer consumer = new WaitingConsumer(); - container.followOutput(consumer, OutputFrame.OutputType.STDOUT); + container.get().followOutput(consumer, OutputFrame.OutputType.STDOUT); consumer.waitUntil(frame -> { return frame.getType() == OutputFrame.OutputType.STDOUT && frame.getUtf8String().contains("seq=2"); @@ -82,7 +84,7 @@ public void testLogConsumer() throws TimeoutException { Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(LOGGER); Consumer composedConsumer = logConsumer.andThen(waitingConsumer); - container.followOutput(composedConsumer); + container.get().followOutput(composedConsumer); waitingConsumer.waitUntil(frame -> { return frame.getType() == OutputFrame.OutputType.STDOUT && frame.getUtf8String().contains("seq=2"); @@ -95,7 +97,7 @@ public void testToStringConsumer() throws TimeoutException { ToStringConsumer toStringConsumer = new ToStringConsumer(); Consumer composedConsumer = toStringConsumer.andThen(waitingConsumer); - container.followOutput(composedConsumer); + container.get().followOutput(composedConsumer); waitingConsumer.waitUntilEnd(30, TimeUnit.SECONDS); diff --git a/core/src/test/java/org/testcontainers/junit/OutputStreamWithTTYTest.java b/core/src/test/java/org/testcontainers/junit/OutputStreamWithTTYTest.java index c340f26d3fb..a43598383dd 100644 --- a/core/src/test/java/org/testcontainers/junit/OutputStreamWithTTYTest.java +++ b/core/src/test/java/org/testcontainers/junit/OutputStreamWithTTYTest.java @@ -11,6 +11,7 @@ import org.testcontainers.containers.output.ToStringConsumer; import org.testcontainers.containers.output.WaitingConsumer; import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy; +import org.testcontainers.junit4.TestcontainersRule; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -23,10 +24,12 @@ public class OutputStreamWithTTYTest { @Rule - public GenericContainer container = new GenericContainer<>(TestImages.ALPINE_IMAGE) - .withCommand("ls -1") - .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) - .withCreateContainerCmdModifier(command -> command.withTty(true)); + public TestcontainersRule> container = new TestcontainersRule<>( + new GenericContainer<>(TestImages.ALPINE_IMAGE) + .withCommand("ls -1") + .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) + .withCreateContainerCmdModifier(command -> command.withTty(true)) + ); @Rule public Timeout globalTimeout = Timeout.seconds(10); @@ -35,7 +38,7 @@ public class OutputStreamWithTTYTest { public void testFetchStdout() throws TimeoutException { WaitingConsumer consumer = new WaitingConsumer(); - container.followOutput(consumer, OutputFrame.OutputType.STDOUT); + container.get().followOutput(consumer, OutputFrame.OutputType.STDOUT); consumer.waitUntil( frame -> { @@ -50,7 +53,7 @@ public void testFetchStdout() throws TimeoutException { public void testFetchStdoutWithTimeout() { WaitingConsumer consumer = new WaitingConsumer(); - container.followOutput(consumer, OutputFrame.OutputType.STDOUT); + container.get().followOutput(consumer, OutputFrame.OutputType.STDOUT); assertThat( catchThrowable(() -> { @@ -73,7 +76,7 @@ public void testFetchStdoutWithTimeout() { public void testFetchStdoutWithNoLimit() throws TimeoutException { WaitingConsumer consumer = new WaitingConsumer(); - container.followOutput(consumer, OutputFrame.OutputType.STDOUT); + container.get().followOutput(consumer, OutputFrame.OutputType.STDOUT); consumer.waitUntil(frame -> { return frame.getType() == OutputFrame.OutputType.STDOUT && frame.getUtf8String().contains("home"); @@ -86,7 +89,7 @@ public void testLogConsumer() throws TimeoutException { Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(log); Consumer composedConsumer = logConsumer.andThen(waitingConsumer); - container.followOutput(composedConsumer); + container.get().followOutput(composedConsumer); waitingConsumer.waitUntil(frame -> { return frame.getType() == OutputFrame.OutputType.STDOUT && frame.getUtf8String().contains("home"); @@ -99,7 +102,7 @@ public void testToStringConsumer() throws TimeoutException { ToStringConsumer toStringConsumer = new ToStringConsumer(); Consumer composedConsumer = toStringConsumer.andThen(waitingConsumer); - container.followOutput(composedConsumer); + container.get().followOutput(composedConsumer); waitingConsumer.waitUntilEnd(4, TimeUnit.SECONDS); diff --git a/core/src/test/java/org/testcontainers/junit/ParameterizedDockerfileContainerTest.java b/core/src/test/java/org/testcontainers/junit/ParameterizedDockerfileContainerTest.java index 8437123f97a..242a2cade81 100644 --- a/core/src/test/java/org/testcontainers/junit/ParameterizedDockerfileContainerTest.java +++ b/core/src/test/java/org/testcontainers/junit/ParameterizedDockerfileContainerTest.java @@ -6,6 +6,7 @@ import org.junit.runners.Parameterized; import org.testcontainers.containers.GenericContainer; import org.testcontainers.images.builder.ImageFromDockerfile; +import org.testcontainers.junit4.TestcontainersRule; import static org.assertj.core.api.Assertions.assertThat; @@ -19,21 +20,23 @@ public class ParameterizedDockerfileContainerTest { private final String expectedVersion; @Rule - public GenericContainer container; + public TestcontainersRule> container; public ParameterizedDockerfileContainerTest(String baseImage, String expectedVersion) { container = - new GenericContainer( - new ImageFromDockerfile() - .withDockerfileFromBuilder(builder -> { - builder - .from(baseImage) - // Could potentially customise the image here, e.g. adding files, running - // commands, etc. - .build(); - }) - ) - .withCommand("top"); + new TestcontainersRule<>( + new GenericContainer<>( + new ImageFromDockerfile() + .withDockerfileFromBuilder(builder -> { + builder + .from(baseImage) + // Could potentially customise the image here, e.g. adding files, running + // commands, etc. + .build(); + }) + ) + .withCommand("top") + ); this.expectedVersion = expectedVersion; } @@ -50,7 +53,7 @@ public static Object[][] data() { @Test public void simpleTest() throws Exception { - final String release = container.execInContainer("cat", "/etc/alpine-release").getStdout(); + final String release = container.get().execInContainer("cat", "/etc/alpine-release").getStdout(); assertThat(release).as("/etc/alpine-release starts with " + expectedVersion).startsWith(expectedVersion); } diff --git a/core/src/test/java/org/testcontainers/junit/WorkingDirectoryTest.java b/core/src/test/java/org/testcontainers/junit/WorkingDirectoryTest.java index 05f65e1f493..417c1dac95a 100644 --- a/core/src/test/java/org/testcontainers/junit/WorkingDirectoryTest.java +++ b/core/src/test/java/org/testcontainers/junit/WorkingDirectoryTest.java @@ -5,6 +5,7 @@ import org.testcontainers.TestImages; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy; +import org.testcontainers.junit4.TestcontainersRule; import static org.assertj.core.api.Assertions.assertThat; @@ -14,14 +15,16 @@ public class WorkingDirectoryTest { @ClassRule - public static GenericContainer container = new GenericContainer(TestImages.ALPINE_IMAGE) - .withWorkingDirectory("/etc") - .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) - .withCommand("ls", "-al"); + public static TestcontainersRule> container = new TestcontainersRule<>( + new GenericContainer(TestImages.ALPINE_IMAGE) + .withWorkingDirectory("/etc") + .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) + .withCommand("ls", "-al") + ); @Test public void checkOutput() { - String listing = container.getLogs(); + String listing = container.get().getLogs(); assertThat(listing).as("Directory listing contains expected /etc content").contains("hostname"); assertThat(listing).as("Directory listing contains expected /etc content").contains("init.d"); 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 bed23566899..4019a26ca41 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 @@ -7,6 +7,7 @@ import org.testcontainers.TestImages; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit4.TestcontainersRule; import java.time.Duration; @@ -20,11 +21,13 @@ public class HostPortWaitStrategyTest { public static class DefaultHostPortWaitStrategyTest { @ClassRule - 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))); + public static TestcontainersRule> container = new TestcontainersRule<>( + 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))) + ); @Test public void testWaiting() {} @@ -33,11 +36,13 @@ public void testWaiting() {} public static class ExplicitHostPortWaitStrategyTest { @ClassRule - public static GenericContainer container = new GenericContainer<>(TestImages.ALPINE_IMAGE) - .withExposedPorts() - .withCommand("sh", "-c", "while true; do nc -lp 8080; done") - .withExposedPorts(8080) - .waitingFor(Wait.forListeningPorts(8080).withStartupTimeout(Duration.ofSeconds(10))); + public static TestcontainersRule> container = new TestcontainersRule<>( + new GenericContainer<>(TestImages.ALPINE_IMAGE) + .withExposedPorts() + .withCommand("sh", "-c", "while true; do nc -lp 8080; done") + .withExposedPorts(8080) + .waitingFor(Wait.forListeningPorts(8080).withStartupTimeout(Duration.ofSeconds(10))) + ); @Test public void testWaiting() {} diff --git a/core/src/test/java/org/testcontainers/utility/AuthenticatedImagePullTest.java b/core/src/test/java/org/testcontainers/utility/AuthenticatedImagePullTest.java index 0e00dd87bf7..f70b5168fbf 100644 --- a/core/src/test/java/org/testcontainers/utility/AuthenticatedImagePullTest.java +++ b/core/src/test/java/org/testcontainers/utility/AuthenticatedImagePullTest.java @@ -13,6 +13,7 @@ import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.GenericContainer; import org.testcontainers.images.builder.ImageFromDockerfile; +import org.testcontainers.junit4.TestcontainersRule; import java.io.IOException; import java.nio.file.Files; @@ -38,27 +39,29 @@ public class AuthenticatedImagePullTest { * Containerised docker image registry, with simple hardcoded credentials */ @ClassRule - public static DockerRegistryContainer authenticatedRegistry = new DockerRegistryContainer( - new ImageFromDockerfile() - .withDockerfileFromBuilder(builder -> { - builder - .from(TestImages.DOCKER_REGISTRY_IMAGE.asCanonicalNameString()) - .run("htpasswd -Bbn testuser notasecret > /htpasswd") - .env("REGISTRY_AUTH", "htpasswd") - .env("REGISTRY_AUTH_HTPASSWD_PATH", "/htpasswd") - .env("REGISTRY_AUTH_HTPASSWD_REALM", "Test"); - }) + public static TestcontainersRule authenticatedRegistry = new TestcontainersRule<>( + new DockerRegistryContainer( + new ImageFromDockerfile() + .withDockerfileFromBuilder(builder -> { + builder + .from(TestImages.DOCKER_REGISTRY_IMAGE.asCanonicalNameString()) + .run("htpasswd -Bbn testuser notasecret > /htpasswd") + .env("REGISTRY_AUTH", "htpasswd") + .env("REGISTRY_AUTH_HTPASSWD_PATH", "/htpasswd") + .env("REGISTRY_AUTH_HTPASSWD_REALM", "Test"); + }) + ) ); private static RegistryAuthLocator originalAuthLocatorSingleton; - private final DockerImageName testImageName = authenticatedRegistry.createImage(); + private final DockerImageName testImageName = authenticatedRegistry.get().createImage(); @BeforeClass public static void beforeClass() throws Exception { originalAuthLocatorSingleton = RegistryAuthLocator.instance(); - String testRegistryAddress = authenticatedRegistry.getEndpoint(); + String testRegistryAddress = authenticatedRegistry.get().getEndpoint(); final AuthConfig authConfig = new AuthConfig() .withUsername("testuser") diff --git a/docs/examples/junit4/generic/build.gradle b/docs/examples/junit4/generic/build.gradle index 5a276cf6a7f..e298c0bb1d5 100644 --- a/docs/examples/junit4/generic/build.gradle +++ b/docs/examples/junit4/generic/build.gradle @@ -3,6 +3,7 @@ description = "Examples for docs" dependencies { testImplementation "junit:junit:4.13.2" testImplementation project(":testcontainers") + testImplementation project(':junit4') testImplementation project(":selenium") testImplementation project(":mysql") 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 52c7f621d07..aa1514734ac 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/CmdModifierTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/CmdModifierTest.java @@ -7,6 +7,7 @@ import org.testcontainers.DockerClientFactory; import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import java.io.IOException; @@ -18,8 +19,10 @@ public class CmdModifierTest { // hostname { @Rule - public GenericContainer theCache = new GenericContainer<>(DockerImageName.parse("redis:6-alpine")) - .withCreateContainerCmdModifier(cmd -> cmd.withHostName("the-cache")); + public TestcontainersRule> theCache = new TestcontainersRule<>( + new GenericContainer<>(DockerImageName.parse("redis:6-alpine")) + .withCreateContainerCmdModifier(cmd -> cmd.withHostName("the-cache")) + ); // } @@ -30,25 +33,28 @@ public class CmdModifierTest { private long memorySwapInBytes = 64l * 1024l * 1024l; @Rule - public GenericContainer memoryLimitedRedis = new GenericContainer<>(DockerImageName.parse("redis:6-alpine")) - .withCreateContainerCmdModifier(cmd -> { - cmd.getHostConfig() - .withMemory(memoryInBytes) - .withMemorySwap(memorySwapInBytes); - }); + public TestcontainersRule> memoryLimitedRedis = new TestcontainersRule<>( + new GenericContainer<>(DockerImageName.parse("redis:6-alpine")) + .withCreateContainerCmdModifier(cmd -> { + cmd.getHostConfig() + .withMemory(memoryInBytes) + .withMemorySwap(memorySwapInBytes); + })); // } // spotless:on @Test public void testHostnameModified() throws IOException, InterruptedException { - final Container.ExecResult execResult = theCache.execInContainer("hostname"); + final Container.ExecResult execResult = theCache.get().execInContainer("hostname"); assertThat(execResult.getStdout().trim()).isEqualTo("the-cache"); } @Test public void testMemoryLimitModified() throws IOException, InterruptedException { - final Container.ExecResult execResult = memoryLimitedRedis.execInContainer("cat", getMemoryLimitFilePath()); + final Container.ExecResult execResult = memoryLimitedRedis + .get() + .execInContainer("cat", getMemoryLimitFilePath()); assertThat(execResult.getStdout().trim()).isEqualTo(String.valueOf(memoryInBytes)); } 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 5b4df0dbb66..2635c5b9e0d 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/CommandsTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/CommandsTest.java @@ -3,6 +3,7 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import static org.assertj.core.api.Assertions.assertThat; @@ -11,13 +12,15 @@ public class CommandsTest { @Rule // startupCommand { - public GenericContainer redisWithCustomPort = new GenericContainer(DockerImageName.parse("redis:6-alpine")) - .withCommand("redis-server --port 7777") - // } - .withExposedPorts(7777); + public TestcontainersRule> redisWithCustomPort = new TestcontainersRule<>( + new GenericContainer(DockerImageName.parse("redis:6-alpine")) + .withCommand("redis-server --port 7777") + // } + .withExposedPorts(7777) + ); @Test public void testStartupCommandOverrideApplied() { - assertThat(redisWithCustomPort.isRunning()).isTrue(); // good enough to check that the container started listening + assertThat(redisWithCustomPort.get().isRunning()).isTrue(); // good enough to check that the container started listening } } 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 e202580c247..ec22b6b4879 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/ContainerCreationTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/ContainerCreationTest.java @@ -3,6 +3,7 @@ import org.junit.ClassRule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import static org.assertj.core.api.Assertions.assertThat; @@ -14,8 +15,9 @@ public class ContainerCreationTest { public static final DockerImageName REDIS_IMAGE = DockerImageName.parse("redis:6-alpine"); @ClassRule - public static GenericContainer redis = new GenericContainer<>(REDIS_IMAGE) - .withExposedPorts(6379); + public static TestcontainersRule> redis = new TestcontainersRule<>( + new GenericContainer<>(REDIS_IMAGE) + .withExposedPorts(6379)); // } // spotless:on @@ -28,18 +30,19 @@ public class ContainerCreationTest { // command and exposed ports. This just listens on port 80 // and always returns '42' @ClassRule - public static GenericContainer alpine = new GenericContainer<>(ALPINE_IMAGE) - .withExposedPorts(80) - .withEnv("MAGIC_NUMBER", "42") - .withCommand("/bin/sh", "-c", - "while true; do echo \"$MAGIC_NUMBER\" | nc -l -p 80; done"); + public static TestcontainersRule> alpine = new TestcontainersRule<>( + new GenericContainer<>(ALPINE_IMAGE) + .withExposedPorts(80) + .withEnv("MAGIC_NUMBER", "42") + .withCommand("/bin/sh", "-c", + "while true; do echo \"$MAGIC_NUMBER\" | nc -l -p 80; done")); // } // spotless:on @Test public void testStartup() { - assertThat(redis.isRunning()).isTrue(); // good enough to check that the container started listening - assertThat(alpine.isRunning()).isTrue(); // good enough to check that the container started listening + assertThat(redis.get().isRunning()).isTrue(); // good enough to check that the container started listening + assertThat(alpine.get().isRunning()).isTrue(); // good enough to check that the container started listening } } 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 73dac2bda9b..3966421b59d 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/ContainerLabelTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/ContainerLabelTest.java @@ -1,6 +1,7 @@ package generic; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import java.util.HashMap; @@ -9,15 +10,17 @@ public class ContainerLabelTest { // single_label { - public GenericContainer containerWithLabel = new GenericContainer(DockerImageName.parse("alpine:3.17")) - .withLabel("key", "value"); + public TestcontainersRule> containerWithLabel = new TestcontainersRule<>( + new GenericContainer(DockerImageName.parse("alpine:3.17")).withLabel("key", "value") + ); // } // multiple_labels { private Map mapOfLabels = new HashMap<>(); // populate map, e.g. mapOfLabels.put("key1", "value1"); - public GenericContainer containerWithMultipleLabels = new GenericContainer(DockerImageName.parse("alpine:3.17")) - .withLabels(mapOfLabels); + public TestcontainersRule> containerWithMultipleLabels = new TestcontainersRule<>( + new GenericContainer(DockerImageName.parse("alpine:3.17")).withLabels(mapOfLabels) + ); // } } diff --git a/docs/examples/junit4/generic/src/test/java/generic/DependsOnTest.java b/docs/examples/junit4/generic/src/test/java/generic/DependsOnTest.java index c48d55899f0..d008fe8bdb0 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/DependsOnTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/DependsOnTest.java @@ -3,6 +3,7 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit4.TestcontainersRule; import static org.assertj.core.api.Assertions.assertThat; @@ -10,18 +11,20 @@ public class DependsOnTest { @Rule // dependsOn { - public GenericContainer redis = new GenericContainer<>("redis:6-alpine").withExposedPorts(6379); + public TestcontainersRule> redis = new TestcontainersRule<>( + new GenericContainer<>("redis:6-alpine").withExposedPorts(6379) + ); @Rule - public GenericContainer nginx = new GenericContainer<>("nginx:1.27.0-alpine3.19-slim") - .dependsOn(redis) - .withExposedPorts(80); + public TestcontainersRule> nginx = new TestcontainersRule<>( + new GenericContainer<>("nginx:1.27.0-alpine3.19-slim").dependsOn(redis.get()).withExposedPorts(80) + ); // } @Test public void testContainersAllStarted() { - assertThat(redis.isRunning()).isTrue(); - assertThat(nginx.isRunning()).isTrue(); + assertThat(redis.get().isRunning()).isTrue(); + assertThat(nginx.get().isRunning()).isTrue(); } } 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 078e177242f..84df662190f 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.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import java.io.IOException; @@ -13,17 +14,18 @@ public class ExecTest { @Rule - public GenericContainer container = new GenericContainer<>(DockerImageName.parse("alpine:3.17")) - .withCommand("top"); + public TestcontainersRule> container = new TestcontainersRule<>( + new GenericContainer<>(DockerImageName.parse("alpine:3.17")).withCommand("top") + ); @Test public void testSimpleExec() throws IOException, InterruptedException { // standaloneExec { - container.execInContainer("touch", "/somefile.txt"); + container.get().execInContainer("touch", "/somefile.txt"); // } // execReadingStdout { - Container.ExecResult lsResult = container.execInContainer("ls", "-al", "/"); + Container.ExecResult lsResult = container.get().execInContainer("ls", "-al", "/"); String stdout = lsResult.getStdout(); int exitCode = lsResult.getExitCode(); assertThat(stdout).contains("somefile.txt"); diff --git a/docs/examples/junit4/generic/src/test/java/generic/HostPortExposedTest.java b/docs/examples/junit4/generic/src/test/java/generic/HostPortExposedTest.java index 392fb22c2a9..7a18d4ea13d 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/HostPortExposedTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/HostPortExposedTest.java @@ -9,6 +9,7 @@ import org.openqa.selenium.remote.RemoteWebDriver; import org.testcontainers.Testcontainers; import org.testcontainers.containers.BrowserWebDriverContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.io.OutputStream; import java.net.InetSocketAddress; @@ -50,15 +51,16 @@ public static void tearDown() throws Exception { } @Rule - public BrowserWebDriverContainer browser = new BrowserWebDriverContainer<>() - .withCapabilities(new ChromeOptions()); + public TestcontainersRule> browser = new TestcontainersRule<>( + new BrowserWebDriverContainer<>().withCapabilities(new ChromeOptions()) + ); @Test public void testContainerRunningAgainstExposedHostPort() { // useHostExposedPort { final String rootUrl = String.format("http://host.testcontainers.internal:%d/", localServerPort); - final RemoteWebDriver webDriver = new RemoteWebDriver(this.browser.getSeleniumAddress(), new ChromeOptions()); + final RemoteWebDriver webDriver = new RemoteWebDriver(browser.get().getSeleniumAddress(), new ChromeOptions()); webDriver.get(rootUrl); // } 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 49e62cff217..bcd683be2ed 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/MultiplePortsExposedTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/MultiplePortsExposedTest.java @@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; public class MultiplePortsExposedTest { @@ -14,32 +15,32 @@ public class MultiplePortsExposedTest { @Rule // rule { - public GenericContainer container = new GenericContainer<>( - DockerImageName.parse("testcontainers/helloworld:1.1.0") - ) - .withExposedPorts(8080, 8081) - .withLogConsumer(new Slf4jLogConsumer(log)); + public TestcontainersRule> container = new TestcontainersRule<>( + new GenericContainer<>(DockerImageName.parse("testcontainers/helloworld:1.1.0")) + .withExposedPorts(8080, 8081) + .withLogConsumer(new Slf4jLogConsumer(log)) + ); // } @Test public void fetchPortsByNumber() { - Integer firstMappedPort = container.getMappedPort(8080); - Integer secondMappedPort = container.getMappedPort(8081); + Integer firstMappedPort = container.get().getMappedPort(8080); + Integer secondMappedPort = container.get().getMappedPort(8081); } @Test public void fetchFirstMappedPort() { - Integer firstMappedPort = container.getFirstMappedPort(); + Integer firstMappedPort = container.get().getFirstMappedPort(); } @Test public void getHostOnly() { - String ipAddress = container.getHost(); + String ipAddress = container.get().getHost(); } @Test public void getHostAndMappedPort() { - String address = container.getHost() + ":" + container.getMappedPort(8080); + String address = container.get().getHost() + ":" + container.get().getMappedPort(8080); } } 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 c66fc9443d0..14703dd8d7b 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.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import static org.assertj.core.api.Assertions.assertThat; @@ -14,26 +15,30 @@ public class WaitStrategiesTest { @Rule // waitForNetworkListening { - public GenericContainer nginx = new GenericContainer(DockerImageName.parse("nginx:1.27.0-alpine3.19-slim")) // - .withExposedPorts(80); + public TestcontainersRule> nginx = new TestcontainersRule<>( + new GenericContainer(DockerImageName.parse("nginx:1.27.0-alpine3.19-slim")) // + .withExposedPorts(80) + ); // } @Rule // waitForSimpleHttp { - public GenericContainer nginxWithHttpWait = new GenericContainer( - DockerImageName.parse("nginx:1.27.0-alpine3.19-slim") - ) - .withExposedPorts(80) - .waitingFor(Wait.forHttp("/")); + public TestcontainersRule> nginxWithHttpWait = new TestcontainersRule<>( + new GenericContainer(DockerImageName.parse("nginx:1.27.0-alpine3.19-slim")) + .withExposedPorts(80) + .waitingFor(Wait.forHttp("/")) + ); // } @Rule // logMessageWait { - public GenericContainer containerWithLogWait = new GenericContainer(DockerImageName.parse("redis:6-alpine")) - .withExposedPorts(6379) - .waitingFor(Wait.forLogMessage(".*Ready to accept connections.*\\n", 1)); + public TestcontainersRule> containerWithLogWait = new TestcontainersRule<>( + new GenericContainer(DockerImageName.parse("redis:6-alpine")) + .withExposedPorts(6379) + .waitingFor(Wait.forLogMessage(".*Ready to accept connections.*\\n", 1)) + ); // } @@ -71,8 +76,8 @@ public class WaitStrategiesTest { @Test public void testContainersAllStarted() { - assertThat(nginx.isRunning()).isTrue(); - assertThat(nginxWithHttpWait.isRunning()).isTrue(); - assertThat(containerWithLogWait.isRunning()).isTrue(); + assertThat(nginx.get().isRunning()).isTrue(); + assertThat(nginxWithHttpWait.get().isRunning()).isTrue(); + assertThat(containerWithLogWait.get().isRunning()).isTrue(); } } diff --git a/docs/examples/junit4/redis/build.gradle b/docs/examples/junit4/redis/build.gradle index 2a0bfb73e7c..e949bd9bcc9 100644 --- a/docs/examples/junit4/redis/build.gradle +++ b/docs/examples/junit4/redis/build.gradle @@ -5,5 +5,6 @@ dependencies { testImplementation "junit:junit:4.13.2" testImplementation project(":testcontainers") + testImplementation project(":junit4") testImplementation 'org.assertj:assertj-core:3.26.3' } 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 e4c4424315b..18b3d107ba3 100644 --- a/docs/examples/junit4/redis/src/test/java/quickstart/RedisBackedCacheIntTest.java +++ b/docs/examples/junit4/redis/src/test/java/quickstart/RedisBackedCacheIntTest.java @@ -4,6 +4,7 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import static org.assertj.core.api.Assertions.assertThat; @@ -14,15 +15,16 @@ public class RedisBackedCacheIntTest { // rule { @Rule - public GenericContainer redis = new GenericContainer(DockerImageName.parse("redis:6-alpine")) - .withExposedPorts(6379); + public TestcontainersRule> redis = new TestcontainersRule<>( + new GenericContainer<>(DockerImageName.parse("redis:6-alpine")).withExposedPorts(6379) + ); // } @Before public void setUp() { - String address = redis.getHost(); - Integer port = redis.getFirstMappedPort(); + String address = redis.get().getHost(); + Integer port = redis.get().getFirstMappedPort(); // Now we have an address and port for Redis, no matter where it is running underTest = new RedisBackedCache(address, port); diff --git a/docs/modules/databases/db2.md b/docs/modules/databases/db2.md index 945536cac05..e7e3e49ac0e 100644 --- a/docs/modules/databases/db2.md +++ b/docs/modules/databases/db2.md @@ -13,12 +13,13 @@ Running DB2 as a stand-in for in a test: public class SomeTest { @ClassRule - public Db2Container db2 = new Db2Container() - .acceptLicense(); + public TestcontainersRule db2 = new TestcontainersRule<>( + new Db2Container().acceptLicense() + ); @Test public void someTestMethod() { - String url = db2.getJdbcUrl(); + String url = db2.get().getJdbcUrl(); ... create a connection and run test as normal } diff --git a/docs/quickstart/junit_4_quickstart.md b/docs/quickstart/junit_4_quickstart.md index 57946c1fb74..62afac29b5e 100644 --- a/docs/quickstart/junit_4_quickstart.md +++ b/docs/quickstart/junit_4_quickstart.md @@ -1,6 +1,9 @@ # JUnit 4 Quickstart -It's easy to add Testcontainers to your project - let's walk through a quick example to see how. +This example shows the way you could use Testcontainers with JUnit 4. + +!!! note + JUnit 4 is in [maintenance mode since 2025-05-31](https://github.com/junit-team/junit4), so we recommend using JUnit 5 or newer versions instead. Let's imagine we have a simple program that has a dependency on Redis, and we want to add some tests for it. In our imaginary program, there is a `RedisBackedCache` class which stores data in Redis. @@ -23,7 +26,8 @@ First, add Testcontainers as a dependency as follows: === "Gradle" ```groovy - testImplementation "org.testcontainers:testcontainers:{{latest_version}}" + testImplementation("org.testcontainers:testcontainers:{{latest_version}}") + testImplementation("org.testcontainers:junit4:{{latest_version}}") ``` === "Maven" ```xml @@ -33,18 +37,26 @@ First, add Testcontainers as a dependency as follows: {{latest_version}} test + + org.testcontainers + junit4 + {{latest_version}} + test + ``` ## 2. Get Testcontainers to run a Redis container during our tests -Simply add the following to the body of our test class: +Add the following to the body of our test class: [JUnit 4 Rule](../examples/junit4/redis/src/test/java/quickstart/RedisBackedCacheIntTest.java) inside_block:rule The `@Rule` annotation tells JUnit to notify this field about various events in the test lifecycle. -In this case, our rule object is a Testcontainers `GenericContainer`, configured to use a specific Redis image from Docker Hub, and configured to expose a port. +Wrap the containers with `new TestContainersRule(...)` so the containers start and stop, according to the test lifecycle. +In this case, our rule object is not `static`, so the container will start and stop with every test. +The test configures `GenericContainer` to use a specific Redis image from Docker Hub, and to expose a port. If we run our test as-is, then regardless of the actual test outcome, we'll see logs showing us that Testcontainers: diff --git a/docs/test_framework_integration/junit_4.md b/docs/test_framework_integration/junit_4.md index 8ab753e611f..312f1dc91bc 100644 --- a/docs/test_framework_integration/junit_4.md +++ b/docs/test_framework_integration/junit_4.md @@ -9,7 +9,7 @@ Add a `@Rule` or `@ClassRule` annotated field to your test class, e.g.: ```java public class SimpleMySQLTest { @Rule - public MySQLContainer mysql = new MySQLContainer(); + public TestcontainersRule mysql = new TestcontainersRule<>(new MySQLContainer()); // [...] } diff --git a/modules/activemq/build.gradle b/modules/activemq/build.gradle index dc20113a84b..664b2829192 100644 --- a/modules/activemq/build.gradle +++ b/modules/activemq/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: ActiveMQ" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation "org.apache.activemq:activemq-client:6.1.2" testImplementation "org.apache.activemq:artemis-jakarta-client:2.37.0" diff --git a/modules/azure/build.gradle b/modules/azure/build.gradle index 1b4242b4eb6..60d2a25dda6 100644 --- a/modules/azure/build.gradle +++ b/modules/azure/build.gradle @@ -6,6 +6,8 @@ dependencies { // TODO use JDK's HTTP client and/or Apache HttpClient5 shaded 'com.squareup.okhttp3:okhttp:4.12.0' + testImplementation project(':junit4') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'com.azure:azure-cosmos:4.63.3' testImplementation 'com.azure:azure-storage-blob:12.29.0' diff --git a/modules/azure/src/test/java/org/testcontainers/azure/EventHubsEmulatorContainerTest.java b/modules/azure/src/test/java/org/testcontainers/azure/EventHubsEmulatorContainerTest.java index 58d1d7ad59c..523bd5f7121 100644 --- a/modules/azure/src/test/java/org/testcontainers/azure/EventHubsEmulatorContainerTest.java +++ b/modules/azure/src/test/java/org/testcontainers/azure/EventHubsEmulatorContainerTest.java @@ -10,6 +10,7 @@ import org.junit.Rule; import org.junit.Test; import org.testcontainers.containers.Network; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.MountableFile; import java.time.Duration; @@ -23,26 +24,27 @@ public class EventHubsEmulatorContainerTest { @Rule // network { - public Network network = Network.newNetwork(); + public TestcontainersRule network = new TestcontainersRule<>(Network.newNetwork()); // } @Rule // azuriteContainer { - public AzuriteContainer azuriteContainer = new AzuriteContainer("mcr.microsoft.com/azure-storage/azurite:3.33.0") - .withNetwork(network); + public TestcontainersRule azuriteContainer = new TestcontainersRule<>( + new AzuriteContainer("mcr.microsoft.com/azure-storage/azurite:3.33.0").withNetwork(network.get()) + ); // } @Rule // emulatorContainer { - public EventHubsEmulatorContainer emulator = new EventHubsEmulatorContainer( - "mcr.microsoft.com/azure-messaging/eventhubs-emulator:2.0.1" - ) - .acceptLicense() - .withNetwork(network) - .withConfig(MountableFile.forClasspathResource("/eventhubs_config.json")) - .withAzuriteContainer(azuriteContainer); + public TestcontainersRule emulator = new TestcontainersRule<>( + new EventHubsEmulatorContainer("mcr.microsoft.com/azure-messaging/eventhubs-emulator:2.0.1") + .acceptLicense() + .withNetwork(network.get()) + .withConfig(MountableFile.forClasspathResource("/eventhubs_config.json")) + .withAzuriteContainer(azuriteContainer.get()) + ); // } @@ -51,12 +53,12 @@ public void testWithEventHubsClient() { try ( // createProducerAndConsumer { EventHubProducerClient producer = new EventHubClientBuilder() - .connectionString(emulator.getConnectionString()) + .connectionString(emulator.get().getConnectionString()) .fullyQualifiedNamespace("emulatorNs1") .eventHubName("eh1") .buildProducerClient(); EventHubConsumerClient consumer = new EventHubClientBuilder() - .connectionString(emulator.getConnectionString()) + .connectionString(emulator.get().getConnectionString()) .fullyQualifiedNamespace("emulatorNs1") .eventHubName("eh1") .consumerGroup("cg1") diff --git a/modules/azure/src/test/java/org/testcontainers/azure/ServiceBusEmulatorContainerTest.java b/modules/azure/src/test/java/org/testcontainers/azure/ServiceBusEmulatorContainerTest.java index 4676e41784a..3032d7f5d47 100644 --- a/modules/azure/src/test/java/org/testcontainers/azure/ServiceBusEmulatorContainerTest.java +++ b/modules/azure/src/test/java/org/testcontainers/azure/ServiceBusEmulatorContainerTest.java @@ -13,6 +13,7 @@ import org.junit.Test; import org.testcontainers.containers.MSSQLServerContainer; import org.testcontainers.containers.Network; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.MountableFile; import java.util.List; @@ -27,43 +28,43 @@ public class ServiceBusEmulatorContainerTest { @Rule // network { - public Network network = Network.newNetwork(); + public TestcontainersRule network = new TestcontainersRule<>(Network.newNetwork()); // } @Rule // sqlContainer { - public MSSQLServerContainer mssqlServerContainer = new MSSQLServerContainer<>( - "mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04" - ) - .acceptLicense() - .withPassword("yourStrong(!)Password") - .withCreateContainerCmdModifier(cmd -> { - cmd.getHostConfig().withCapAdd(Capability.SYS_PTRACE); - }) - .withNetwork(network); + public TestcontainersRule> mssqlServerContainer = new TestcontainersRule<>( + new MSSQLServerContainer<>("mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04") + .acceptLicense() + .withPassword("yourStrong(!)Password") + .withCreateContainerCmdModifier(cmd -> { + cmd.getHostConfig().withCapAdd(Capability.SYS_PTRACE); + }) + .withNetwork(network.get()) + ); // } @Rule // emulatorContainer { - public ServiceBusEmulatorContainer emulator = new ServiceBusEmulatorContainer( - "mcr.microsoft.com/azure-messaging/servicebus-emulator:1.1.2" - ) - .acceptLicense() - .withConfig(MountableFile.forClasspathResource("/service-bus-config.json")) - .withNetwork(network) - .withMsSqlServerContainer(mssqlServerContainer); + public TestcontainersRule emulator = new TestcontainersRule<>( + new ServiceBusEmulatorContainer("mcr.microsoft.com/azure-messaging/servicebus-emulator:1.1.2") + .acceptLicense() + .withConfig(MountableFile.forClasspathResource("/service-bus-config.json")) + .withNetwork(network.get()) + .withMsSqlServerContainer(mssqlServerContainer.get()) + ); // } @Test public void testWithClient() { - assertThat(emulator.getConnectionString()).startsWith("Endpoint=sb://"); + assertThat(emulator.get().getConnectionString()).startsWith("Endpoint=sb://"); // senderClient { ServiceBusSenderClient senderClient = new ServiceBusClientBuilder() - .connectionString(emulator.getConnectionString()) + .connectionString(emulator.get().getConnectionString()) .sender() .queueName("queue.1") .buildClient(); @@ -86,7 +87,7 @@ public void testWithClient() { Consumer errorConsumer = e -> Assertions.fail("Unexpected error: " + e); // processorClient { ServiceBusProcessorClient processorClient = new ServiceBusClientBuilder() - .connectionString(emulator.getConnectionString()) + .connectionString(emulator.get().getConnectionString()) .processor() .queueName("queue.1") .processMessage(messageConsumer) diff --git a/modules/azure/src/test/java/org/testcontainers/containers/CosmosDBEmulatorContainerTest.java b/modules/azure/src/test/java/org/testcontainers/containers/CosmosDBEmulatorContainerTest.java index 140bd64c39a..60dd59f0050 100644 --- a/modules/azure/src/test/java/org/testcontainers/containers/CosmosDBEmulatorContainerTest.java +++ b/modules/azure/src/test/java/org/testcontainers/containers/CosmosDBEmulatorContainerTest.java @@ -9,6 +9,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import java.io.FileOutputStream; @@ -37,8 +38,10 @@ public static void restoreOriginalSystemProperties() { @Rule // emulatorContainer { - public CosmosDBEmulatorContainer emulator = new CosmosDBEmulatorContainer( - DockerImageName.parse("mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest") + public TestcontainersRule emulator = new TestcontainersRule<>( + new CosmosDBEmulatorContainer( + DockerImageName.parse("mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest") + ) ); // } @@ -47,20 +50,20 @@ public static void restoreOriginalSystemProperties() { public void testWithCosmosClient() throws Exception { // buildAndSaveNewKeyStore { Path keyStoreFile = tempFolder.newFile("azure-cosmos-emulator.keystore").toPath(); - KeyStore keyStore = emulator.buildNewKeyStore(); - keyStore.store(new FileOutputStream(keyStoreFile.toFile()), emulator.getEmulatorKey().toCharArray()); + KeyStore keyStore = emulator.get().buildNewKeyStore(); + keyStore.store(new FileOutputStream(keyStoreFile.toFile()), emulator.get().getEmulatorKey().toCharArray()); // } // setSystemTrustStoreParameters { System.setProperty("javax.net.ssl.trustStore", keyStoreFile.toString()); - System.setProperty("javax.net.ssl.trustStorePassword", emulator.getEmulatorKey()); + System.setProperty("javax.net.ssl.trustStorePassword", emulator.get().getEmulatorKey()); System.setProperty("javax.net.ssl.trustStoreType", "PKCS12"); // } // buildClient { CosmosAsyncClient client = new CosmosClientBuilder() .gatewayMode() .endpointDiscoveryEnabled(false) - .endpoint(emulator.getEmulatorEndpoint()) - .key(emulator.getEmulatorKey()) + .endpoint(emulator.get().getEmulatorEndpoint()) + .key(emulator.get().getEmulatorKey()) .buildAsyncClient(); // } // testWithClientAgainstEmulatorContainer { diff --git a/modules/cassandra/build.gradle b/modules/cassandra/build.gradle index 3d27fe65cac..a9ee99b6e91 100644 --- a/modules/cassandra/build.gradle +++ b/modules/cassandra/build.gradle @@ -10,6 +10,7 @@ dependencies { api project(":database-commons") api "com.datastax.cassandra:cassandra-driver-core:3.10.0" + testImplementation 'junit:junit:4.13.2' testImplementation 'com.datastax.oss:java-driver-core:4.17.0' testImplementation 'org.assertj:assertj-core:3.26.3' } diff --git a/modules/chromadb/build.gradle b/modules/chromadb/build.gradle index bd6ae52d90f..34d0c06edc0 100644 --- a/modules/chromadb/build.gradle +++ b/modules/chromadb/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: ChromaDB" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'io.rest-assured:rest-assured:5.5.0' } diff --git a/modules/consul/build.gradle b/modules/consul/build.gradle index b2e99d5578e..62771b26406 100644 --- a/modules/consul/build.gradle +++ b/modules/consul/build.gradle @@ -3,6 +3,8 @@ description = "Testcontainers :: Consul" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' + testImplementation project(':junit4') testImplementation 'com.ecwid.consul:consul-api:1.4.5' testImplementation 'io.rest-assured:rest-assured:5.5.0' testImplementation 'org.assertj:assertj-core:3.26.3' diff --git a/modules/consul/src/test/java/org/testcontainers/consul/ConsulContainerTest.java b/modules/consul/src/test/java/org/testcontainers/consul/ConsulContainerTest.java index 7f1c6d1c207..f7623a14740 100644 --- a/modules/consul/src/test/java/org/testcontainers/consul/ConsulContainerTest.java +++ b/modules/consul/src/test/java/org/testcontainers/consul/ConsulContainerTest.java @@ -7,6 +7,7 @@ import org.junit.ClassRule; import org.junit.Test; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -23,12 +24,15 @@ public class ConsulContainerTest { @ClassRule - public static ConsulContainer consulContainer = new ConsulContainer("hashicorp/consul:1.15") - .withConsulCommand("kv put config/testing1 value123"); + public static TestcontainersRule consulContainer = new TestcontainersRule<>( + new ConsulContainer("hashicorp/consul:1.15").withConsulCommand("kv put config/testing1 value123") + ); @Test public void readFirstPropertyPathWithCli() throws IOException, InterruptedException { - GenericContainer.ExecResult result = consulContainer.execInContainer("consul", "kv", "get", "config/testing1"); + GenericContainer.ExecResult result = consulContainer + .get() + .execInContainer("consul", "kv", "get", "config/testing1"); final String output = result.getStdout().replaceAll("\\r?\\n", ""); assertThat(output).contains("value123"); } @@ -48,8 +52,8 @@ public void readFirstSecretPathOverHttpApi() { @Test public void writeAndReadMultipleValuesUsingClient() { final ConsulClient consulClient = new ConsulClient( - consulContainer.getHost(), - consulContainer.getFirstMappedPort() + consulContainer.get().getHost(), + consulContainer.get().getFirstMappedPort() ); final Map properties = new HashMap<>(); @@ -70,6 +74,6 @@ public void writeAndReadMultipleValuesUsingClient() { } private String getHostAndPort() { - return consulContainer.getHost() + ":" + consulContainer.getMappedPort(8500); + return consulContainer.get().getHost() + ":" + consulContainer.get().getMappedPort(8500); } } diff --git a/modules/couchbase/build.gradle b/modules/couchbase/build.gradle index 973af4b2ffb..fcde06cb4aa 100644 --- a/modules/couchbase/build.gradle +++ b/modules/couchbase/build.gradle @@ -5,6 +5,7 @@ dependencies { // TODO use JDK's HTTP client and/or Apache HttpClient5 shaded 'com.squareup.okhttp3:okhttp:4.12.0' + testImplementation 'junit:junit:4.13.2' testImplementation 'com.couchbase.client:java-client:3.7.3' testImplementation 'org.awaitility:awaitility:4.2.0' testImplementation 'org.assertj:assertj-core:3.26.3' diff --git a/modules/database-commons/build.gradle b/modules/database-commons/build.gradle index 2a1ead4c215..f7c4633e465 100644 --- a/modules/database-commons/build.gradle +++ b/modules/database-commons/build.gradle @@ -3,5 +3,6 @@ description = "Testcontainers :: Database-Commons" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' } diff --git a/modules/dynalite/build.gradle b/modules/dynalite/build.gradle index d8fe2377b76..a9c5c005318 100644 --- a/modules/dynalite/build.gradle +++ b/modules/dynalite/build.gradle @@ -3,6 +3,8 @@ description = "Testcontainers :: Dynalite (deprecated)" dependencies { api project(':testcontainers') + testImplementation project(':junit4') + testImplementation 'junit:junit:4.13.2' compileOnly 'com.amazonaws:aws-java-sdk-dynamodb:1.12.772' testImplementation 'com.amazonaws:aws-java-sdk-dynamodb:1.12.772' testImplementation 'org.assertj:assertj-core:3.26.3' 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 2a4e94e9516..e4e9b0c831e 100644 --- a/modules/dynalite/src/test/java/org/testcontainers/dynamodb/DynaliteContainerTest.java +++ b/modules/dynalite/src/test/java/org/testcontainers/dynamodb/DynaliteContainerTest.java @@ -12,6 +12,7 @@ import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import static org.assertj.core.api.Assertions.assertThat; @@ -24,14 +25,16 @@ public class DynaliteContainerTest { ); @Rule - public DynaliteContainer dynamoDB = new DynaliteContainer(DYNALITE_IMAGE); + public TestcontainersRule dynamoDB = new TestcontainersRule<>( + new DynaliteContainer(DYNALITE_IMAGE) + ); @Test public void simpleTestWithManualClientCreation() { final AmazonDynamoDB client = AmazonDynamoDBClientBuilder .standard() - .withEndpointConfiguration(dynamoDB.getEndpointConfiguration()) - .withCredentials(dynamoDB.getCredentials()) + .withEndpointConfiguration(dynamoDB.get().getEndpointConfiguration()) + .withCredentials(dynamoDB.get().getCredentials()) .build(); runTest(client); @@ -39,7 +42,7 @@ public void simpleTestWithManualClientCreation() { @Test public void simpleTestWithProvidedClient() { - final AmazonDynamoDB client = dynamoDB.getClient(); + final AmazonDynamoDB client = dynamoDB.get().getClient(); runTest(client); } diff --git a/modules/elasticsearch/build.gradle b/modules/elasticsearch/build.gradle index 79faefdde24..0706beb9563 100644 --- a/modules/elasticsearch/build.gradle +++ b/modules/elasticsearch/build.gradle @@ -2,6 +2,7 @@ description = "Testcontainers :: elasticsearch" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation "org.elasticsearch.client:elasticsearch-rest-client:8.15.1" testImplementation "org.elasticsearch.client:transport:7.17.24" testImplementation 'org.assertj:assertj-core:3.26.3' diff --git a/modules/gcloud/build.gradle b/modules/gcloud/build.gradle index cb55e466e22..e5bb498496a 100644 --- a/modules/gcloud/build.gradle +++ b/modules/gcloud/build.gradle @@ -3,6 +3,8 @@ description = "Testcontainers :: GCloud" dependencies { api project(':testcontainers') + testImplementation project(':junit4') + testImplementation 'junit:junit:4.13.2' testImplementation platform("com.google.cloud:libraries-bom:26.43.0") testImplementation 'com.google.cloud:google-cloud-bigquery' testImplementation 'com.google.cloud:google-cloud-datastore' diff --git a/modules/gcloud/src/test/java/org/testcontainers/containers/BigtableEmulatorContainerTest.java b/modules/gcloud/src/test/java/org/testcontainers/containers/BigtableEmulatorContainerTest.java index 8a100855b3c..7d1403ceac4 100644 --- a/modules/gcloud/src/test/java/org/testcontainers/containers/BigtableEmulatorContainerTest.java +++ b/modules/gcloud/src/test/java/org/testcontainers/containers/BigtableEmulatorContainerTest.java @@ -20,6 +20,7 @@ import io.grpc.ManagedChannelBuilder; import org.junit.Rule; import org.junit.Test; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import java.io.IOException; @@ -35,8 +36,10 @@ public class BigtableEmulatorContainerTest { @Rule // emulatorContainer { - public BigtableEmulatorContainer emulator = new BigtableEmulatorContainer( - DockerImageName.parse("gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0-emulators") + public TestcontainersRule emulator = new TestcontainersRule<>( + new BigtableEmulatorContainer( + DockerImageName.parse("gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0-emulators") + ) ); // } @@ -44,7 +47,10 @@ public class BigtableEmulatorContainerTest { @Test // testWithEmulatorContainer { public void testSimple() throws IOException { - ManagedChannel channel = ManagedChannelBuilder.forTarget(emulator.getEmulatorEndpoint()).usePlaintext().build(); + ManagedChannel channel = ManagedChannelBuilder + .forTarget(emulator.get().getEmulatorEndpoint()) + .usePlaintext() + .build(); TransportChannelProvider channelProvider = FixedTransportChannelProvider.create( GrpcTransportChannel.create(channel) @@ -54,7 +60,7 @@ public void testSimple() throws IOException { try ( BigtableDataClient client = BigtableDataClient.create( BigtableDataSettings - .newBuilderForEmulator(emulator.getHost(), emulator.getEmulatorPort()) + .newBuilderForEmulator(emulator.get().getHost(), emulator.get().getEmulatorPort()) .setProjectId(PROJECT_ID) .setInstanceId(INSTANCE_ID) .build() diff --git a/modules/gcloud/src/test/java/org/testcontainers/containers/DatastoreEmulatorContainerTest.java b/modules/gcloud/src/test/java/org/testcontainers/containers/DatastoreEmulatorContainerTest.java index 7ea0ceb9a49..4bbba0da687 100644 --- a/modules/gcloud/src/test/java/org/testcontainers/containers/DatastoreEmulatorContainerTest.java +++ b/modules/gcloud/src/test/java/org/testcontainers/containers/DatastoreEmulatorContainerTest.java @@ -8,6 +8,7 @@ import com.google.cloud.datastore.Key; import org.junit.Rule; import org.junit.Test; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import java.io.IOException; @@ -18,8 +19,10 @@ public class DatastoreEmulatorContainerTest { @Rule // creatingDatastoreEmulatorContainer { - public DatastoreEmulatorContainer emulator = new DatastoreEmulatorContainer( - DockerImageName.parse("gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0-emulators") + public TestcontainersRule emulator = new TestcontainersRule<>( + new DatastoreEmulatorContainer( + DockerImageName.parse("gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0-emulators") + ) ); // } @@ -29,10 +32,10 @@ public class DatastoreEmulatorContainerTest { public void testSimple() { DatastoreOptions options = DatastoreOptions .newBuilder() - .setHost(emulator.getEmulatorEndpoint()) + .setHost(emulator.get().getEmulatorEndpoint()) .setCredentials(NoCredentials.getInstance()) .setRetrySettings(ServiceOptions.getNoRetrySettings()) - .setProjectId(emulator.getProjectId()) + .setProjectId(emulator.get().getProjectId()) .build(); Datastore datastore = options.getService(); diff --git a/modules/gcloud/src/test/java/org/testcontainers/containers/FirestoreEmulatorContainerTest.java b/modules/gcloud/src/test/java/org/testcontainers/containers/FirestoreEmulatorContainerTest.java index 0d9773ce87a..313311efdee 100644 --- a/modules/gcloud/src/test/java/org/testcontainers/containers/FirestoreEmulatorContainerTest.java +++ b/modules/gcloud/src/test/java/org/testcontainers/containers/FirestoreEmulatorContainerTest.java @@ -10,6 +10,7 @@ import com.google.cloud.firestore.WriteResult; import org.junit.Rule; import org.junit.Test; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import java.util.HashMap; @@ -22,8 +23,10 @@ public class FirestoreEmulatorContainerTest { @Rule // emulatorContainer { - public FirestoreEmulatorContainer emulator = new FirestoreEmulatorContainer( - DockerImageName.parse("gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0-emulators") + public TestcontainersRule emulator = new TestcontainersRule<>( + new FirestoreEmulatorContainer( + DockerImageName.parse("gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0-emulators") + ) ); // } @@ -34,7 +37,7 @@ public void testSimple() throws ExecutionException, InterruptedException { FirestoreOptions options = FirestoreOptions .getDefaultInstance() .toBuilder() - .setHost(emulator.getEmulatorEndpoint()) + .setHost(emulator.get().getEmulatorEndpoint()) .setCredentials(NoCredentials.getInstance()) .setProjectId("test-project") .build(); diff --git a/modules/gcloud/src/test/java/org/testcontainers/containers/PubSubEmulatorContainerTest.java b/modules/gcloud/src/test/java/org/testcontainers/containers/PubSubEmulatorContainerTest.java index b2f75f0f36a..cac4c2c1a30 100644 --- a/modules/gcloud/src/test/java/org/testcontainers/containers/PubSubEmulatorContainerTest.java +++ b/modules/gcloud/src/test/java/org/testcontainers/containers/PubSubEmulatorContainerTest.java @@ -24,6 +24,7 @@ import io.grpc.ManagedChannelBuilder; import org.junit.Rule; import org.junit.Test; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import java.io.IOException; @@ -36,8 +37,10 @@ public class PubSubEmulatorContainerTest { @Rule // emulatorContainer { - public PubSubEmulatorContainer emulator = new PubSubEmulatorContainer( - DockerImageName.parse("gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0-emulators") + public TestcontainersRule emulator = new TestcontainersRule<>( + new PubSubEmulatorContainer( + DockerImageName.parse("gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0-emulators") + ) ); // } @@ -45,7 +48,7 @@ public class PubSubEmulatorContainerTest { @Test // testWithEmulatorContainer { public void testSimple() throws IOException { - String hostport = emulator.getEmulatorEndpoint(); + String hostport = emulator.get().getEmulatorEndpoint(); ManagedChannel channel = ManagedChannelBuilder.forTarget(hostport).usePlaintext().build(); try { TransportChannelProvider channelProvider = FixedTransportChannelProvider.create( diff --git a/modules/gcloud/src/test/java/org/testcontainers/containers/SpannerEmulatorContainerTest.java b/modules/gcloud/src/test/java/org/testcontainers/containers/SpannerEmulatorContainerTest.java index b246e7e1f0d..54373a48a2b 100644 --- a/modules/gcloud/src/test/java/org/testcontainers/containers/SpannerEmulatorContainerTest.java +++ b/modules/gcloud/src/test/java/org/testcontainers/containers/SpannerEmulatorContainerTest.java @@ -16,6 +16,7 @@ import com.google.cloud.spanner.Statement; import org.junit.Rule; import org.junit.Test; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import java.util.Arrays; @@ -27,8 +28,8 @@ public class SpannerEmulatorContainerTest { @Rule // emulatorContainer { - public SpannerEmulatorContainer emulator = new SpannerEmulatorContainer( - DockerImageName.parse("gcr.io/cloud-spanner-emulator/emulator:1.4.0") + public TestcontainersRule emulator = new TestcontainersRule<>( + new SpannerEmulatorContainer(DockerImageName.parse("gcr.io/cloud-spanner-emulator/emulator:1.4.0")) ); // } @@ -44,7 +45,7 @@ public class SpannerEmulatorContainerTest { public void testSimple() throws ExecutionException, InterruptedException { SpannerOptions options = SpannerOptions .newBuilder() - .setEmulatorHost(emulator.getEmulatorGrpcEndpoint()) + .setEmulatorHost(emulator.get().getEmulatorGrpcEndpoint()) .setCredentials(NoCredentials.getInstance()) .setProjectId(PROJECT_NAME) .build(); diff --git a/modules/grafana/build.gradle b/modules/grafana/build.gradle index d5c815018d0..559f4c28189 100644 --- a/modules/grafana/build.gradle +++ b/modules/grafana/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: Grafana" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'io.rest-assured:rest-assured:5.5.0' testImplementation 'io.micrometer:micrometer-registry-otlp:1.13.4' diff --git a/modules/influxdb/build.gradle b/modules/influxdb/build.gradle index 9cf1e8d5ab0..69b6c09d973 100644 --- a/modules/influxdb/build.gradle +++ b/modules/influxdb/build.gradle @@ -5,6 +5,7 @@ dependencies { compileOnly 'org.influxdb:influxdb-java:2.24' + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'org.influxdb:influxdb-java:2.24' testImplementation "com.influxdb:influxdb-client-java:6.12.0" diff --git a/modules/jdbc/build.gradle b/modules/jdbc/build.gradle index 2b2868ebbc6..a6f6db5b1fe 100644 --- a/modules/jdbc/build.gradle +++ b/modules/jdbc/build.gradle @@ -4,6 +4,7 @@ dependencies { api project(':database-commons') compileOnly 'org.jetbrains:annotations:24.1.0' + testImplementation 'junit:junit:4.13.2' testImplementation 'commons-dbutils:commons-dbutils:1.8.1' testImplementation 'org.vibur:vibur-dbcp:25.0' testImplementation 'org.apache.tomcat:tomcat-jdbc:10.1.30' diff --git a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestLifecycleAwareExceptionCapturingTest.java b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestLifecycleAwareExceptionCapturingTest.java index b64f2f3c328..2412182a73c 100644 --- a/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestLifecycleAwareExceptionCapturingTest.java +++ b/modules/junit-jupiter/src/test/java/org/testcontainers/junit/jupiter/TestLifecycleAwareExceptionCapturingTest.java @@ -1,13 +1,13 @@ package org.testcontainers.junit.jupiter; -import org.junit.AssumptionViolatedException; import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; +import org.opentest4j.TestAbortedException; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; // The order of @ExtendsWith and @Testcontainers is crucial in order for the tests @Testcontainers @@ -31,7 +31,7 @@ void failing_test_should_pass_throwable_to_testContainer() { @Order(2) void should_have_captured_thrownException() { Throwable capturedThrowable = startedTestContainer.getCapturedThrowable(); - assertThat(capturedThrowable).isInstanceOf(AssumptionViolatedException.class); + assertThat(capturedThrowable).isInstanceOf(TestAbortedException.class); assertThat(capturedThrowable.getMessage()).isEqualTo("got: , expected: is "); } } diff --git a/modules/junit4/build.gradle b/modules/junit4/build.gradle new file mode 100644 index 00000000000..522eb5d97a0 --- /dev/null +++ b/modules/junit4/build.gradle @@ -0,0 +1,9 @@ +description = "Testcontainers :: Cassandra" + +dependencies { + api project(":testcontainers") + api 'junit:junit:4.13.2' + + testImplementation 'com.datastax.oss:java-driver-core:4.17.0' + testImplementation 'org.assertj:assertj-core:3.26.3' +} diff --git a/modules/junit4/src/main/java/org/testcontainers/junit4/TestcontainersRule.java b/modules/junit4/src/main/java/org/testcontainers/junit4/TestcontainersRule.java new file mode 100644 index 00000000000..86320bb2443 --- /dev/null +++ b/modules/junit4/src/main/java/org/testcontainers/junit4/TestcontainersRule.java @@ -0,0 +1,42 @@ +package org.testcontainers.junit4; + +import org.junit.rules.ExternalResource; +import org.testcontainers.lifecycle.Startable; + +/** + * Integrates Testcontainers with JUnit4 lifecycle. + */ +public class TestcontainersRule extends ExternalResource { + + private final T resource; + + public TestcontainersRule(T resource) { + this.resource = resource; + } + + /** + * Returns the managed resource. + * @return the managed resource + */ + public T get() { + return resource; + } + + @Override + protected void before() throws Throwable { + super.before(); + T resource = this.resource; + if (resource instanceof Startable) { + ((Startable) resource).start(); + } + } + + @Override + protected void after() { + try { + resource.close(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/modules/k3s/build.gradle b/modules/k3s/build.gradle index 3f795d99743..d736766c5f9 100644 --- a/modules/k3s/build.gradle +++ b/modules/k3s/build.gradle @@ -8,7 +8,9 @@ dependencies { // Any >2.8 version here is not compatible with jackson-databind 2.8.x. shaded 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.8.8' + testImplementation project(':junit4') testImplementation 'io.fabric8:kubernetes-client:6.13.1' testImplementation 'io.kubernetes:client-java:21.0.1-legacy' + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' } diff --git a/modules/k3s/src/test/java/org/testcontainers/k3s/KubectlContainerTest.java b/modules/k3s/src/test/java/org/testcontainers/k3s/KubectlContainerTest.java index 5c0d44ff0f1..fb49400a2eb 100644 --- a/modules/k3s/src/test/java/org/testcontainers/k3s/KubectlContainerTest.java +++ b/modules/k3s/src/test/java/org/testcontainers/k3s/KubectlContainerTest.java @@ -6,6 +6,7 @@ import org.testcontainers.containers.Network; import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy; import org.testcontainers.images.builder.Transferable; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import java.time.Duration; @@ -17,13 +18,15 @@ public class KubectlContainerTest { public static Network network = Network.SHARED; @ClassRule - public static K3sContainer k3s = new K3sContainer(DockerImageName.parse("rancher/k3s:v1.21.3-k3s1")) - .withNetwork(network) - .withNetworkAliases("k3s"); + public static TestcontainersRule k3s = new TestcontainersRule<>( + new K3sContainer(DockerImageName.parse("rancher/k3s:v1.21.3-k3s1")) + .withNetwork(network) + .withNetworkAliases("k3s") + ); @Test public void shouldExposeKubeConfigForNetworkAlias() throws Exception { - String kubeConfigYaml = k3s.generateInternalKubeConfigYaml("k3s"); + String kubeConfigYaml = k3s.get().generateInternalKubeConfigYaml("k3s"); try ( GenericContainer kubectlContainer = new GenericContainer<>("rancher/kubectl:v1.23.3") @@ -40,6 +43,6 @@ public void shouldExposeKubeConfigForNetworkAlias() throws Exception { @Test(expected = IllegalArgumentException.class) public void shouldThrowAnExceptionForUnknownNetworkAlias() { - k3s.generateInternalKubeConfigYaml("not-set-network-alias"); + k3s.get().generateInternalKubeConfigYaml("not-set-network-alias"); } } diff --git a/modules/k6/build.gradle b/modules/k6/build.gradle index 5bf8d773da0..431a6f18b3d 100644 --- a/modules/k6/build.gradle +++ b/modules/k6/build.gradle @@ -3,5 +3,6 @@ description = "Testcontainers :: k6" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' } diff --git a/modules/kafka/build.gradle b/modules/kafka/build.gradle index 5f0658a51d0..63d91de1d83 100644 --- a/modules/kafka/build.gradle +++ b/modules/kafka/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: Kafka" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.apache.kafka:kafka-clients:3.8.0' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'com.google.guava:guava:23.0' diff --git a/modules/ldap/build.gradle b/modules/ldap/build.gradle index 52366d06737..f99ad1818f8 100644 --- a/modules/ldap/build.gradle +++ b/modules/ldap/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: LDAP" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'com.unboundid:unboundid-ldapsdk:7.0.2' } diff --git a/modules/localstack/build.gradle b/modules/localstack/build.gradle index 2994bb7d2f2..639f99c10e2 100644 --- a/modules/localstack/build.gradle +++ b/modules/localstack/build.gradle @@ -4,11 +4,13 @@ dependencies { api project(':testcontainers') testImplementation platform("com.amazonaws:aws-java-sdk-bom:1.12.572") + testImplementation project(':junit4') testImplementation 'com.amazonaws:aws-java-sdk-s3' testImplementation 'com.amazonaws:aws-java-sdk-sqs' testImplementation 'com.amazonaws:aws-java-sdk-logs' testImplementation 'com.amazonaws:aws-java-sdk-lambda' testImplementation 'com.amazonaws:aws-java-sdk-core' + testImplementation 'junit:junit:4.13.2' testImplementation 'software.amazon.awssdk:s3:2.28.6' testImplementation 'org.assertj:assertj-core:3.26.3' } 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 a1c36078840..c13c300cc55 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 @@ -42,6 +42,7 @@ import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.localstack.LocalStackContainer.Service; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; @@ -81,14 +82,16 @@ public static class WithoutNetwork { // without_network { @ClassRule - public static LocalStackContainer localstack = new LocalStackContainer(LocalstackTestImages.LOCALSTACK_IMAGE) - .withServices( - Service.S3, - Service.SQS, - Service.CLOUDWATCHLOGS, - Service.KMS, - LocalStackContainer.EnabledService.named("events") - ); + public static TestcontainersRule localstack = new TestcontainersRule<>( + new LocalStackContainer(LocalstackTestImages.LOCALSTACK_IMAGE) + .withServices( + Service.S3, + Service.SQS, + Service.CLOUDWATCHLOGS, + Service.KMS, + LocalStackContainer.EnabledService.named("events") + ) + ); // } @@ -99,13 +102,13 @@ public void s3TestOverBridgeNetwork() throws IOException { .standard() .withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration( - localstack.getEndpoint().toString(), - localstack.getRegion() + localstack.get().getEndpoint().toString(), + localstack.get().getRegion() ) ) .withCredentials( new AWSStaticCredentialsProvider( - new BasicAWSCredentials(localstack.getAccessKey(), localstack.getSecretKey()) + new BasicAWSCredentials(localstack.get().getAccessKey(), localstack.get().getSecretKey()) ) ) .build(); @@ -138,13 +141,13 @@ public void s3TestUsingAwsSdkV2() { // with_aws_sdk_v2 { S3Client s3 = S3Client .builder() - .endpointOverride(localstack.getEndpoint()) + .endpointOverride(localstack.get().getEndpoint()) .credentialsProvider( StaticCredentialsProvider.create( - AwsBasicCredentials.create(localstack.getAccessKey(), localstack.getSecretKey()) + AwsBasicCredentials.create(localstack.get().getAccessKey(), localstack.get().getSecretKey()) ) ) - .region(Region.of(localstack.getRegion())) + .region(Region.of(localstack.get().getRegion())) .build(); // } @@ -161,13 +164,13 @@ public void sqsTestOverBridgeNetwork() { .standard() .withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration( - localstack.getEndpoint().toString(), - localstack.getRegion() + localstack.get().getEndpoint().toString(), + localstack.get().getRegion() ) ) .withCredentials( new AWSStaticCredentialsProvider( - new BasicAWSCredentials(localstack.getAccessKey(), localstack.getSecretKey()) + new BasicAWSCredentials(localstack.get().getAccessKey(), localstack.get().getSecretKey()) ) ) .build(); @@ -176,7 +179,12 @@ public void sqsTestOverBridgeNetwork() { String fooQueueUrl = queueResult.getQueueUrl(); assertThat(fooQueueUrl) .as("Created queue has external hostname URL") - .contains("http://" + localstack.getHost() + ":" + localstack.getMappedPort(LocalStackContainer.PORT)); + .contains( + "http://" + + localstack.get().getHost() + + ":" + + localstack.get().getMappedPort(LocalStackContainer.PORT) + ); sqs.sendMessage(fooQueueUrl, "test"); final long messageCount = sqs @@ -194,13 +202,13 @@ public void cloudWatchLogsTestOverBridgeNetwork() { .standard() .withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration( - localstack.getEndpoint().toString(), - localstack.getRegion() + localstack.get().getEndpoint().toString(), + localstack.get().getRegion() ) ) .withCredentials( new AWSStaticCredentialsProvider( - new BasicAWSCredentials(localstack.getAccessKey(), localstack.getSecretKey()) + new BasicAWSCredentials(localstack.get().getAccessKey(), localstack.get().getSecretKey()) ) ) .build(); @@ -218,13 +226,13 @@ public void kmsKeyCreationTest() { .standard() .withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration( - localstack.getEndpoint().toString(), - localstack.getRegion() + localstack.get().getEndpoint().toString(), + localstack.get().getRegion() ) ) .withCredentials( new AWSStaticCredentialsProvider( - new BasicAWSCredentials(localstack.getAccessKey(), localstack.getSecretKey()) + new BasicAWSCredentials(localstack.get().getAccessKey(), localstack.get().getSecretKey()) ) ) .build(); @@ -241,22 +249,22 @@ public void kmsKeyCreationTest() { @Test public void samePortIsExposedForAllServices() { - assertThat(localstack.getExposedPorts()).as("A single port is exposed").hasSize(1); - assertThat(localstack.getEndpointOverride(Service.SQS).toString()) + assertThat(localstack.get().getExposedPorts()).as("A single port is exposed").hasSize(1); + assertThat(localstack.get().getEndpointOverride(Service.SQS).toString()) .as("Endpoint overrides are different") - .isEqualTo(localstack.getEndpointOverride(Service.S3).toString()); + .isEqualTo(localstack.get().getEndpointOverride(Service.S3).toString()); assertThat( new AwsClientBuilder.EndpointConfiguration( - localstack.getEndpointOverride(Service.SQS).toString(), - localstack.getRegion() + localstack.get().getEndpointOverride(Service.SQS).toString(), + localstack.get().getRegion() ) .getServiceEndpoint() ) .as("Endpoint configuration have different endpoints") .isEqualTo( new AwsClientBuilder.EndpointConfiguration( - localstack.getEndpointOverride(Service.S3).toString(), - localstack.getRegion() + localstack.get().getEndpointOverride(Service.S3).toString(), + localstack.get().getRegion() ) .getServiceEndpoint() ); @@ -269,29 +277,29 @@ public static class WithNetwork { private static Network network = Network.newNetwork(); @ClassRule - public static LocalStackContainer localstackInDockerNetwork = new LocalStackContainer( - LocalstackTestImages.LOCALSTACK_IMAGE - ) - .withNetwork(network) - .withNetworkAliases("notthis", "localstack") // the last alias is used for HOSTNAME_EXTERNAL - .withServices(Service.S3, Service.SQS, Service.CLOUDWATCHLOGS); + public static TestcontainersRule localstackInDockerNetwork = new TestcontainersRule<>( + new LocalStackContainer(LocalstackTestImages.LOCALSTACK_IMAGE) + .withNetwork(network) + .withNetworkAliases("notthis", "localstack") // the last alias is used for HOSTNAME_EXTERNAL + .withServices(Service.S3, Service.SQS, Service.CLOUDWATCHLOGS) + ); // } @ClassRule - public static GenericContainer awsCliInDockerNetwork = new GenericContainer<>( - LocalstackTestImages.AWS_CLI_IMAGE - ) - .withNetwork(network) - .withCreateContainerCmdModifier(cmd -> cmd.withEntrypoint("tail")) - .withCommand(" -f /dev/null") - .withEnv("AWS_ACCESS_KEY_ID", "accesskey") - .withEnv("AWS_SECRET_ACCESS_KEY", "secretkey") - .withEnv("AWS_REGION", "eu-west-1"); + public static TestcontainersRule> awsCliInDockerNetwork = new TestcontainersRule<>( + new GenericContainer<>(LocalstackTestImages.AWS_CLI_IMAGE) + .withNetwork(network) + .withCreateContainerCmdModifier(cmd -> cmd.withEntrypoint("tail")) + .withCommand(" -f /dev/null") + .withEnv("AWS_ACCESS_KEY_ID", "accesskey") + .withEnv("AWS_SECRET_ACCESS_KEY", "secretkey") + .withEnv("AWS_REGION", "eu-west-1") + ); @Test public void localstackHostEnVarIsSet() { - assertThat(localstackInDockerNetwork.getEnvMap().get("HOSTNAME_EXTERNAL")).isEqualTo("localstack"); + assertThat(localstackInDockerNetwork.get().getEnvMap().get("HOSTNAME_EXTERNAL")).isEqualTo("localstack"); } @Test @@ -344,7 +352,7 @@ private String runAwsCliAgainstDockerNetworkContainer(String command) throws Exc LocalStackContainer.PORT ) .split(" "); - final Container.ExecResult execResult = awsCliInDockerNetwork.execInContainer(commandParts); + final Container.ExecResult execResult = awsCliInDockerNetwork.get().execInContainer(commandParts); assertThat(execResult.getExitCode()).isEqualTo(0); final String logs = execResult.getStdout() + execResult.getStderr(); @@ -359,17 +367,19 @@ public static class WithRegion { private static String region = "eu-west-1"; @ClassRule - public static LocalStackContainer localstack = new LocalStackContainer(LocalstackTestImages.LOCALSTACK_IMAGE) - .withEnv("DEFAULT_REGION", region) - .withServices(Service.S3); + public static TestcontainersRule localstack = new TestcontainersRule<>( + new LocalStackContainer(LocalstackTestImages.LOCALSTACK_IMAGE) + .withEnv("DEFAULT_REGION", region) + .withServices(Service.S3) + ); // } @Test public void s3EndpointHasProperRegion() { final AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration( - localstack.getEndpoint().toString(), - localstack.getRegion() + localstack.get().getEndpoint().toString(), + localstack.get().getRegion() ); assertThat(endpointConfiguration.getSigningRegion()) .as("The endpoint configuration has right region") @@ -380,8 +390,8 @@ public void s3EndpointHasProperRegion() { public static class WithoutServices { @ClassRule - public static LocalStackContainer localstack = new LocalStackContainer( - LocalstackTestImages.LOCALSTACK_0_13_IMAGE + public static TestcontainersRule localstack = new TestcontainersRule<>( + new LocalStackContainer(LocalstackTestImages.LOCALSTACK_0_13_IMAGE) ); @Test @@ -389,13 +399,13 @@ public void s3ServiceStartLazily() { try ( S3Client s3 = S3Client .builder() - .endpointOverride(localstack.getEndpoint()) + .endpointOverride(localstack.get().getEndpoint()) .credentialsProvider( StaticCredentialsProvider.create( - AwsBasicCredentials.create(localstack.getAccessKey(), localstack.getSecretKey()) + AwsBasicCredentials.create(localstack.get().getAccessKey(), localstack.get().getSecretKey()) ) ) - .region(Region.of(localstack.getRegion())) + .region(Region.of(localstack.get().getRegion())) .build() ) { assertThat(s3.listBuckets().buckets()).as("S3 Service is started lazily").isEmpty(); @@ -408,26 +418,26 @@ public static class WithVersion2 { private static Network network = Network.newNetwork(); @ClassRule - public static LocalStackContainer localstack = new LocalStackContainer( - DockerImageName.parse("localstack/localstack:2.0") - ) - .withNetwork(network) - .withNetworkAliases("localstack"); + public static TestcontainersRule localstack = new TestcontainersRule<>( + new LocalStackContainer(DockerImageName.parse("localstack/localstack:2.0")) + .withNetwork(network) + .withNetworkAliases("localstack") + ); @ClassRule - public static GenericContainer awsCliInDockerNetwork = new GenericContainer<>( - LocalstackTestImages.AWS_CLI_IMAGE - ) - .withNetwork(network) - .withCreateContainerCmdModifier(cmd -> cmd.withEntrypoint("tail")) - .withCommand(" -f /dev/null") - .withEnv("AWS_ACCESS_KEY_ID", "accesskey") - .withEnv("AWS_SECRET_ACCESS_KEY", "secretkey") - .withEnv("AWS_REGION", "eu-west-1"); + public static TestcontainersRule> awsCliInDockerNetwork = new TestcontainersRule<>( + new GenericContainer<>(LocalstackTestImages.AWS_CLI_IMAGE) + .withNetwork(network) + .withCreateContainerCmdModifier(cmd -> cmd.withEntrypoint("tail")) + .withCommand(" -f /dev/null") + .withEnv("AWS_ACCESS_KEY_ID", "accesskey") + .withEnv("AWS_SECRET_ACCESS_KEY", "secretkey") + .withEnv("AWS_REGION", "eu-west-1") + ); @Test public void localstackHostEnVarIsSet() { - assertThat(localstack.getEnvMap().get("LOCALSTACK_HOST")).isEqualTo("localstack"); + assertThat(localstack.get().getEnvMap().get("LOCALSTACK_HOST")).isEqualTo("localstack"); } @Test @@ -466,7 +476,7 @@ private String runAwsCliAgainstDockerNetworkContainer(String command) throws Exc LocalStackContainer.PORT ) .split(" "); - final Container.ExecResult execResult = awsCliInDockerNetwork.execInContainer(commandParts); + final Container.ExecResult execResult = awsCliInDockerNetwork.get().execInContainer(commandParts); assertThat(execResult.getExitCode()).isEqualTo(0); final String logs = execResult.getStdout() + execResult.getStderr(); @@ -478,10 +488,10 @@ private String runAwsCliAgainstDockerNetworkContainer(String command) throws Exc public static class S3SkipSignatureValidation { @ClassRule - public static LocalStackContainer localstack = new LocalStackContainer( - LocalstackTestImages.LOCALSTACK_2_3_IMAGE - ) - .withEnv("S3_SKIP_SIGNATURE_VALIDATION", "0"); + public static TestcontainersRule localstack = new TestcontainersRule<>( + new LocalStackContainer(LocalstackTestImages.LOCALSTACK_2_3_IMAGE) + .withEnv("S3_SKIP_SIGNATURE_VALIDATION", "0") + ); @Test public void shouldBeAccessibleWithCredentials() throws IOException { @@ -489,13 +499,13 @@ public void shouldBeAccessibleWithCredentials() throws IOException { .standard() .withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration( - localstack.getEndpoint().toString(), - localstack.getRegion() + localstack.get().getEndpoint().toString(), + localstack.get().getRegion() ) ) .withCredentials( new AWSStaticCredentialsProvider( - new BasicAWSCredentials(localstack.getAccessKey(), localstack.getSecretKey()) + new BasicAWSCredentials(localstack.get().getAccessKey(), localstack.get().getSecretKey()) ) ) .build(); @@ -528,8 +538,8 @@ public void shouldBeAccessibleWithCredentials() throws IOException { public static class LambdaContainerLabels { @ClassRule - public static LocalStackContainer localstack = new LocalStackContainer( - LocalstackTestImages.LOCALSTACK_2_3_IMAGE + public static TestcontainersRule localstack = new TestcontainersRule<>( + new LocalStackContainer(LocalstackTestImages.LOCALSTACK_2_3_IMAGE) ); private static byte[] createLambdaHandlerZipFile() throws IOException { @@ -555,13 +565,13 @@ public void shouldLabelLambdaContainers() throws IOException { .standard() .withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration( - localstack.getEndpoint().toString(), - localstack.getRegion() + localstack.get().getEndpoint().toString(), + localstack.get().getRegion() ) ) .withCredentials( new AWSStaticCredentialsProvider( - new BasicAWSCredentials(localstack.getAccessKey(), localstack.getSecretKey()) + new BasicAWSCredentials(localstack.get().getAccessKey(), localstack.get().getSecretKey()) ) ) .build(); @@ -594,7 +604,9 @@ public void shouldLabelLambdaContainers() throws IOException { // assert that the spawned lambda containers has the testcontainers labels set DockerClient dockerClient = DockerClientFactory.instance().client(); - Collection nameFilter = Collections.singleton(localstack.getContainerName().replace("_", "-")); + Collection nameFilter = Collections.singleton( + localstack.get().getContainerName().replace("_", "-") + ); com.github.dockerjava.api.model.Container lambdaContainer = dockerClient .listContainersCmd() .withNameFilter(nameFilter) diff --git a/modules/milvus/build.gradle b/modules/milvus/build.gradle index a15d24bbbe5..cb0f8d456e9 100644 --- a/modules/milvus/build.gradle +++ b/modules/milvus/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: Milvus" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'io.milvus:milvus-sdk-java:2.4.4' } diff --git a/modules/minio/build.gradle b/modules/minio/build.gradle index e4ebe5d0b43..3f9e2e49bd2 100644 --- a/modules/minio/build.gradle +++ b/modules/minio/build.gradle @@ -4,5 +4,6 @@ dependencies { api project(':testcontainers') testImplementation("io.minio:minio:8.5.12") + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' } diff --git a/modules/mockserver/build.gradle b/modules/mockserver/build.gradle index 31f4944a572..36889d9acb5 100644 --- a/modules/mockserver/build.gradle +++ b/modules/mockserver/build.gradle @@ -3,6 +3,8 @@ description = "Testcontainers :: MockServer" dependencies { api project(':testcontainers') + testImplementation project(':junit4') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.mock-server:mockserver-client-java:5.15.0' testImplementation 'org.assertj:assertj-core:3.26.3' } diff --git a/modules/mockserver/src/test/java/org/testcontainers/containers/MockServerContainerRuleTest.java b/modules/mockserver/src/test/java/org/testcontainers/containers/MockServerContainerRuleTest.java index eaf240f0fe2..6a3c1d4361c 100644 --- a/modules/mockserver/src/test/java/org/testcontainers/containers/MockServerContainerRuleTest.java +++ b/modules/mockserver/src/test/java/org/testcontainers/containers/MockServerContainerRuleTest.java @@ -3,6 +3,7 @@ import org.junit.Rule; import org.junit.Test; import org.mockserver.client.MockServerClient; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import static org.assertj.core.api.Assertions.assertThat; @@ -17,7 +18,9 @@ public class MockServerContainerRuleTest { .withTag("mockserver-" + MockServerClient.class.getPackage().getImplementationVersion()); @Rule - public MockServerContainer mockServer = new MockServerContainer(MOCKSERVER_IMAGE); + public TestcontainersRule mockServer = new TestcontainersRule<>( + new MockServerContainer(MOCKSERVER_IMAGE) + ); // } @@ -25,7 +28,10 @@ public class MockServerContainerRuleTest { public void shouldReturnExpectation() throws Exception { // testSimpleExpectation { try ( - MockServerClient mockServerClient = new MockServerClient(mockServer.getHost(), mockServer.getServerPort()) + MockServerClient mockServerClient = new MockServerClient( + mockServer.get().getHost(), + mockServer.get().getServerPort() + ) ) { mockServerClient .when(request().withPath("/person").withQueryStringParameter("name", "peter")) @@ -33,7 +39,7 @@ public void shouldReturnExpectation() throws Exception { // ...a GET request to '/person?name=peter' returns "Peter the person!" - assertThat(SimpleHttpClient.responseFromMockserver(mockServer, "/person?name=peter")) + assertThat(SimpleHttpClient.responseFromMockserver(mockServer.get(), "/person?name=peter")) .as("Expectation returns expected response body") .contains("Peter the person"); } diff --git a/modules/mongodb/build.gradle b/modules/mongodb/build.gradle index 0904df92824..4ecf1baf494 100644 --- a/modules/mongodb/build.gradle +++ b/modules/mongodb/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: MongoDB" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation("org.mongodb:mongodb-driver-sync:5.1.4") testImplementation 'org.assertj:assertj-core:3.26.3' } diff --git a/modules/neo4j/build.gradle b/modules/neo4j/build.gradle index d70292361d1..15210eeb17f 100644 --- a/modules/neo4j/build.gradle +++ b/modules/neo4j/build.gradle @@ -33,6 +33,8 @@ dependencies { api project(":testcontainers") + testImplementation project(':junit4') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.neo4j.driver:neo4j-java-driver:4.4.18' testImplementation 'org.assertj:assertj-core:3.26.3' } 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 b5f9c2ad867..cac18b00e68 100644 --- a/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerJUnitIntegrationTest.java +++ b/modules/neo4j/src/test/java/org/testcontainers/containers/Neo4jContainerJUnitIntegrationTest.java @@ -6,6 +6,7 @@ import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; import org.neo4j.driver.Session; +import org.testcontainers.junit4.TestcontainersRule; import java.util.Collections; @@ -18,15 +19,20 @@ public class Neo4jContainerJUnitIntegrationTest { @ClassRule - public static Neo4jContainer neo4jContainer = new Neo4jContainer<>("neo4j:4.4"); + public static TestcontainersRule> neo4jContainer = new TestcontainersRule<>( + new Neo4jContainer<>("neo4j:4.4") + ); @Test public void shouldStart() { - boolean actual = neo4jContainer.isRunning(); + boolean actual = neo4jContainer.get().isRunning(); assertThat(actual).isTrue(); try ( - Driver driver = GraphDatabase.driver(neo4jContainer.getBoltUrl(), AuthTokens.basic("neo4j", "password")); + Driver driver = GraphDatabase.driver( + neo4jContainer.get().getBoltUrl(), + AuthTokens.basic("neo4j", "password") + ); Session session = driver.session() ) { long one = session.run("RETURN 1", Collections.emptyMap()).next().get(0).asLong(); @@ -38,7 +44,7 @@ public void shouldStart() { @Test public void shouldReturnBoltUrl() { - String actual = neo4jContainer.getBoltUrl(); + String actual = neo4jContainer.get().getBoltUrl(); assertThat(actual).isNotNull(); assertThat(actual).startsWith("bolt://"); @@ -46,7 +52,7 @@ public void shouldReturnBoltUrl() { @Test public void shouldReturnHttpUrl() { - String actual = neo4jContainer.getHttpUrl(); + String actual = neo4jContainer.get().getHttpUrl(); assertThat(actual).isNotNull(); assertThat(actual).startsWith("http://"); diff --git a/modules/nginx/build.gradle b/modules/nginx/build.gradle index 13232b4bfce..fc80e0c139e 100644 --- a/modules/nginx/build.gradle +++ b/modules/nginx/build.gradle @@ -3,5 +3,6 @@ description = "Testcontainers :: Nginx" dependencies { api project(':testcontainers') compileOnly 'org.jetbrains:annotations:24.1.0' + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' } diff --git a/modules/ollama/build.gradle b/modules/ollama/build.gradle index b6054a1d3c2..1fef2198c16 100644 --- a/modules/ollama/build.gradle +++ b/modules/ollama/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: Ollama" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'io.rest-assured:rest-assured:5.5.0' } diff --git a/modules/openfga/build.gradle b/modules/openfga/build.gradle index 6cbbaa91e68..860d23567a8 100644 --- a/modules/openfga/build.gradle +++ b/modules/openfga/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: OpenFGA" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'dev.openfga:openfga-sdk:0.7.0' } diff --git a/modules/orientdb/build.gradle b/modules/orientdb/build.gradle index d353be80783..1d180f60b47 100644 --- a/modules/orientdb/build.gradle +++ b/modules/orientdb/build.gradle @@ -5,6 +5,7 @@ dependencies { api "com.orientechnologies:orientdb-client:3.2.33" + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'org.apache.tinkerpop:gremlin-driver:3.7.2' testImplementation "com.orientechnologies:orientdb-gremlin:3.2.33" diff --git a/modules/pinecone/build.gradle b/modules/pinecone/build.gradle index a78b81a3902..6e091acd8c4 100644 --- a/modules/pinecone/build.gradle +++ b/modules/pinecone/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: ActiveMQ" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'io.pinecone:pinecone-client:3.1.0' } diff --git a/modules/pulsar/build.gradle b/modules/pulsar/build.gradle index 7af1bc777e2..269a70537c7 100644 --- a/modules/pulsar/build.gradle +++ b/modules/pulsar/build.gradle @@ -4,6 +4,7 @@ dependencies { api project(':testcontainers') testImplementation platform("org.apache.pulsar:pulsar-bom:3.3.1") + testImplementation 'junit:junit:4.13.2' testImplementation 'org.apache.pulsar:pulsar-client' testImplementation 'org.apache.pulsar:pulsar-client-admin' testImplementation 'org.assertj:assertj-core:3.26.3' diff --git a/modules/qdrant/build.gradle b/modules/qdrant/build.gradle index 790b22520ae..4ff356dfe7e 100644 --- a/modules/qdrant/build.gradle +++ b/modules/qdrant/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: Qdrant" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'io.qdrant:client:1.10.0' testImplementation platform('io.grpc:grpc-bom:1.68.0') diff --git a/modules/questdb/build.gradle b/modules/questdb/build.gradle index 01bc5473247..697cbafb462 100644 --- a/modules/questdb/build.gradle +++ b/modules/questdb/build.gradle @@ -6,6 +6,7 @@ dependencies { testRuntimeOnly 'org.postgresql:postgresql:42.7.4' testImplementation project(':jdbc-test') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'org.questdb:questdb:7.3.9' testImplementation 'org.awaitility:awaitility:4.2.0' diff --git a/modules/r2dbc/build.gradle b/modules/r2dbc/build.gradle index 1415df161fa..88e620f6105 100644 --- a/modules/r2dbc/build.gradle +++ b/modules/r2dbc/build.gradle @@ -8,10 +8,12 @@ dependencies { api project(':testcontainers') api 'io.r2dbc:r2dbc-spi:0.9.0.RELEASE' + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'io.r2dbc:r2dbc-postgresql:0.8.13.RELEASE' testImplementation project(':postgresql') + testFixturesImplementation 'junit:junit:4.13.2' testFixturesImplementation 'io.projectreactor:reactor-core:3.6.10' testFixturesImplementation 'org.assertj:assertj-core:3.26.3' } diff --git a/modules/rabbitmq/build.gradle b/modules/rabbitmq/build.gradle index 42a12d68759..81ae9efeab9 100644 --- a/modules/rabbitmq/build.gradle +++ b/modules/rabbitmq/build.gradle @@ -2,7 +2,9 @@ description = "Testcontainers :: RabbitMQ" dependencies { api project(":testcontainers") + testImplementation project(':junit4') testImplementation 'com.rabbitmq:amqp-client:5.22.0' + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' compileOnly 'org.jetbrains:annotations:24.1.0' } 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 e04ab616e66..5a1b74037f6 100644 --- a/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQContainerJUnitIntegrationTest.java +++ b/modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQContainerJUnitIntegrationTest.java @@ -2,6 +2,7 @@ import org.junit.ClassRule; import org.junit.Test; +import org.testcontainers.junit4.TestcontainersRule; import static org.assertj.core.api.Assertions.assertThat; @@ -11,10 +12,12 @@ public class RabbitMQContainerJUnitIntegrationTest { @ClassRule - public static RabbitMQContainer rabbitMQContainer = new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE); + public static TestcontainersRule rabbitMQContainer = new TestcontainersRule<>( + new RabbitMQContainer(RabbitMQTestImages.RABBITMQ_IMAGE) + ); @Test public void shouldStart() { - assertThat(rabbitMQContainer.isRunning()).isTrue(); + assertThat(rabbitMQContainer.get().isRunning()).isTrue(); } } diff --git a/modules/redpanda/build.gradle b/modules/redpanda/build.gradle index 2db469936f6..7374f3cebc0 100644 --- a/modules/redpanda/build.gradle +++ b/modules/redpanda/build.gradle @@ -4,6 +4,7 @@ dependencies { api project(':testcontainers') shaded 'org.freemarker:freemarker:2.3.33' + testImplementation 'junit:junit:4.13.2' testImplementation 'org.apache.kafka:kafka-clients:3.8.0' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'io.rest-assured:rest-assured:5.5.0' diff --git a/modules/scylladb/build.gradle b/modules/scylladb/build.gradle index 6d92489ef30..0fba2ea740b 100644 --- a/modules/scylladb/build.gradle +++ b/modules/scylladb/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: ScyllaDB" dependencies { api project(":testcontainers") + testImplementation 'junit:junit:4.13.2' testImplementation 'com.scylladb:java-driver-core:4.15.0.0' testImplementation 'org.assertj:assertj-core:3.24.2' testImplementation 'software.amazon.awssdk:dynamodb:2.28.6' diff --git a/modules/selenium/build.gradle b/modules/selenium/build.gradle index da8ad97f933..acca96858c2 100644 --- a/modules/selenium/build.gradle +++ b/modules/selenium/build.gradle @@ -6,6 +6,8 @@ dependencies { provided 'org.seleniumhq.selenium:selenium-remote-driver:4.10.0' provided 'org.seleniumhq.selenium:selenium-chrome-driver:4.10.0' + testImplementation project(':junit4') + testImplementation 'junit:junit:4.13.2' testImplementation platform('org.seleniumhq.selenium:selenium-bom:4.13.0') testImplementation 'org.seleniumhq.selenium:selenium-firefox-driver' testImplementation 'org.seleniumhq.selenium:selenium-edge-driver' diff --git a/modules/selenium/src/main/java/org/testcontainers/containers/RecordingFileFactory.java b/modules/selenium/src/main/java/org/testcontainers/containers/RecordingFileFactory.java index 31946dac59e..9f3795f7cb8 100644 --- a/modules/selenium/src/main/java/org/testcontainers/containers/RecordingFileFactory.java +++ b/modules/selenium/src/main/java/org/testcontainers/containers/RecordingFileFactory.java @@ -1,20 +1,10 @@ package org.testcontainers.containers; -import org.junit.runner.Description; import org.testcontainers.containers.VncRecordingContainer.VncRecordingFormat; import java.io.File; public interface RecordingFileFactory { - @Deprecated - default File recordingFileForTest(File vncRecordingDirectory, Description description, boolean succeeded) { - return recordingFileForTest( - vncRecordingDirectory, - description.getTestClass().getSimpleName() + "-" + description.getMethodName(), - succeeded - ); - } - default File recordingFileForTest( File vncRecordingDirectory, String prefix, diff --git a/modules/selenium/src/test/java/org/testcontainers/containers/DefaultRecordingFileFactoryTest.java b/modules/selenium/src/test/java/org/testcontainers/containers/DefaultRecordingFileFactoryTest.java index aa894810930..0e0e80173f0 100644 --- a/modules/selenium/src/test/java/org/testcontainers/containers/DefaultRecordingFileFactoryTest.java +++ b/modules/selenium/src/test/java/org/testcontainers/containers/DefaultRecordingFileFactoryTest.java @@ -1,21 +1,12 @@ package org.testcontainers.containers; import lombok.Value; -import org.junit.Test; -import org.junit.runner.Description; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.io.File; -import java.nio.file.Files; -import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; @RunWith(Parameterized.class) @Value @@ -38,35 +29,4 @@ public static Collection data() { args.add(new Object[] { "testMethod2", "PASSED", Boolean.TRUE }); return args; } - - @Test - public void recordingFileThatShouldDescribeTheTestResultAtThePresentTime() throws Exception { - File vncRecordingDirectory = Files.createTempDirectory("recording").toFile(); - Description description = Description.createTestDescription( - getClass().getCanonicalName(), - methodName, - Test.class - ); - - File recordingFile = factory.recordingFileForTest(vncRecordingDirectory, description, success); - - String expectedFilePrefix = String.format("%s-%s-%s", prefix, getClass().getSimpleName(), methodName); - - List expectedPossibleFileNames = Arrays.asList( - new File( - vncRecordingDirectory, - String.format("%s-%s.flv", expectedFilePrefix, LocalDateTime.now().format(DATETIME_FORMATTER)) - ), - new File( - vncRecordingDirectory, - String.format( - "%s-%s.flv", - expectedFilePrefix, - LocalDateTime.now().minusSeconds(1L).format(DATETIME_FORMATTER) - ) - ) - ); - - assertThat(expectedPossibleFileNames).contains(recordingFile); - } } diff --git a/modules/selenium/src/test/java/org/testcontainers/junit/BaseWebDriverContainerTest.java b/modules/selenium/src/test/java/org/testcontainers/junit/BaseWebDriverContainerTest.java index 97124802de1..f646a361d83 100644 --- a/modules/selenium/src/test/java/org/testcontainers/junit/BaseWebDriverContainerTest.java +++ b/modules/selenium/src/test/java/org/testcontainers/junit/BaseWebDriverContainerTest.java @@ -9,6 +9,7 @@ import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; import java.time.Duration; @@ -21,16 +22,16 @@ public class BaseWebDriverContainerTest { @ClassRule - public static Network NETWORK = Network.newNetwork(); + public static TestcontainersRule NETWORK = new TestcontainersRule<>(Network.newNetwork()); @ClassRule - public static GenericContainer HELLO_WORLD = new GenericContainer<>( - DockerImageName.parse("testcontainers/helloworld:1.1.0") - ) - .withNetwork(NETWORK) - .withNetworkAliases("helloworld") - .withExposedPorts(8080, 8081) - .waitingFor(new HttpWaitStrategy()); + public static TestcontainersRule> HELLO_WORLD = new TestcontainersRule<>( + new GenericContainer<>(DockerImageName.parse("testcontainers/helloworld:1.1.0")) + .withNetwork(NETWORK.get()) + .withNetworkAliases("helloworld") + .withExposedPorts(8080, 8081) + .waitingFor(new HttpWaitStrategy()) + ); protected static void doSimpleExplore(BrowserWebDriverContainer rule, Capabilities capabilities) { RemoteWebDriver driver = new RemoteWebDriver(rule.getSeleniumAddress(), capabilities); diff --git a/modules/selenium/src/test/java/org/testcontainers/junit/ChromeWebDriverContainerTest.java b/modules/selenium/src/test/java/org/testcontainers/junit/ChromeWebDriverContainerTest.java index 2f0bfc27b0d..aa10c60b621 100644 --- a/modules/selenium/src/test/java/org/testcontainers/junit/ChromeWebDriverContainerTest.java +++ b/modules/selenium/src/test/java/org/testcontainers/junit/ChromeWebDriverContainerTest.java @@ -5,6 +5,7 @@ import org.junit.Test; import org.openqa.selenium.chrome.ChromeOptions; import org.testcontainers.containers.BrowserWebDriverContainer; +import org.testcontainers.junit4.TestcontainersRule; /** * @@ -13,18 +14,20 @@ public class ChromeWebDriverContainerTest extends BaseWebDriverContainerTest { // junitRule { @Rule - public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer<>() - .withCapabilities(new ChromeOptions()) - // } - .withNetwork(NETWORK); + public TestcontainersRule> chrome = new TestcontainersRule<>( + new BrowserWebDriverContainer<>() + .withCapabilities(new ChromeOptions()) + // } + .withNetwork(NETWORK) + ); @Before public void checkBrowserIsIndeedChrome() { - assertBrowserNameIs(chrome, "chrome", new ChromeOptions()); + assertBrowserNameIs(chrome.get(), "chrome", new ChromeOptions()); } @Test public void simpleExploreTest() { - doSimpleExplore(chrome, new ChromeOptions()); + doSimpleExplore(chrome.get(), new ChromeOptions()); } } diff --git a/modules/selenium/src/test/java/org/testcontainers/junit/ContainerWithoutCapabilitiesTest.java b/modules/selenium/src/test/java/org/testcontainers/junit/ContainerWithoutCapabilitiesTest.java index f5c03fb32d1..2ada3080155 100644 --- a/modules/selenium/src/test/java/org/testcontainers/junit/ContainerWithoutCapabilitiesTest.java +++ b/modules/selenium/src/test/java/org/testcontainers/junit/ContainerWithoutCapabilitiesTest.java @@ -4,19 +4,22 @@ import org.junit.Test; import org.openqa.selenium.chrome.ChromeOptions; import org.testcontainers.containers.BrowserWebDriverContainer; +import org.testcontainers.junit4.TestcontainersRule; public class ContainerWithoutCapabilitiesTest extends BaseWebDriverContainerTest { @Rule - public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer<>().withNetwork(NETWORK); + public TestcontainersRule> chrome = new TestcontainersRule<>( + new BrowserWebDriverContainer<>().withNetwork(NETWORK) + ); @Test public void chromeIsStartedIfNoCapabilitiesProvided() { - assertBrowserNameIs(chrome, "chrome", new ChromeOptions()); + assertBrowserNameIs(chrome.get(), "chrome", new ChromeOptions()); } @Test public void simpleExploreTestWhenNoCapabilitiesProvided() { - doSimpleExplore(chrome, new ChromeOptions()); + doSimpleExplore(chrome.get(), new ChromeOptions()); } } diff --git a/modules/selenium/src/test/java/org/testcontainers/junit/CustomWaitTimeoutWebDriverContainerTest.java b/modules/selenium/src/test/java/org/testcontainers/junit/CustomWaitTimeoutWebDriverContainerTest.java index 43639010e59..2e2d2ec2bc1 100644 --- a/modules/selenium/src/test/java/org/testcontainers/junit/CustomWaitTimeoutWebDriverContainerTest.java +++ b/modules/selenium/src/test/java/org/testcontainers/junit/CustomWaitTimeoutWebDriverContainerTest.java @@ -4,6 +4,7 @@ import org.junit.Test; import org.openqa.selenium.chrome.ChromeOptions; import org.testcontainers.containers.BrowserWebDriverContainer; +import org.testcontainers.junit4.TestcontainersRule; import java.time.Duration; import java.time.temporal.ChronoUnit; @@ -14,13 +15,15 @@ public class CustomWaitTimeoutWebDriverContainerTest extends BaseWebDriverContainerTest { @Rule - public BrowserWebDriverContainer chromeWithCustomTimeout = new BrowserWebDriverContainer<>() - .withCapabilities(new ChromeOptions()) - .withStartupTimeout(Duration.of(30, ChronoUnit.SECONDS)) - .withNetwork(NETWORK); + public TestcontainersRule> chromeWithCustomTimeout = new TestcontainersRule<>( + new BrowserWebDriverContainer<>() + .withCapabilities(new ChromeOptions()) + .withStartupTimeout(Duration.of(30, ChronoUnit.SECONDS)) + .withNetwork(NETWORK) + ); @Test public void simpleExploreTest() { - doSimpleExplore(chromeWithCustomTimeout, new ChromeOptions()); + doSimpleExplore(chromeWithCustomTimeout.get(), new ChromeOptions()); } } diff --git a/modules/selenium/src/test/java/org/testcontainers/junit/EdgeWebDriverContainerTest.java b/modules/selenium/src/test/java/org/testcontainers/junit/EdgeWebDriverContainerTest.java index f1935fa84ee..9231a9d6807 100644 --- a/modules/selenium/src/test/java/org/testcontainers/junit/EdgeWebDriverContainerTest.java +++ b/modules/selenium/src/test/java/org/testcontainers/junit/EdgeWebDriverContainerTest.java @@ -5,23 +5,26 @@ import org.junit.Test; import org.openqa.selenium.edge.EdgeOptions; import org.testcontainers.containers.BrowserWebDriverContainer; +import org.testcontainers.junit4.TestcontainersRule; public class EdgeWebDriverContainerTest extends BaseWebDriverContainerTest { // junitRule { @Rule - public BrowserWebDriverContainer edge = new BrowserWebDriverContainer<>() - .withCapabilities(new EdgeOptions()) - // } - .withNetwork(NETWORK); + public TestcontainersRule> edge = new TestcontainersRule<>( + new BrowserWebDriverContainer<>() + .withCapabilities(new EdgeOptions()) + // } + .withNetwork(NETWORK) + ); @Before public void checkBrowserIsIndeedMSEdge() { - assertBrowserNameIs(edge, "msedge", new EdgeOptions()); + assertBrowserNameIs(edge.get(), "msedge", new EdgeOptions()); } @Test public void simpleExploreTest() { - doSimpleExplore(edge, new EdgeOptions()); + doSimpleExplore(edge.get(), new EdgeOptions()); } } diff --git a/modules/selenium/src/test/java/org/testcontainers/junit/FirefoxWebDriverContainerTest.java b/modules/selenium/src/test/java/org/testcontainers/junit/FirefoxWebDriverContainerTest.java index 211800b8fad..ac60c648712 100644 --- a/modules/selenium/src/test/java/org/testcontainers/junit/FirefoxWebDriverContainerTest.java +++ b/modules/selenium/src/test/java/org/testcontainers/junit/FirefoxWebDriverContainerTest.java @@ -5,6 +5,7 @@ import org.junit.Test; import org.openqa.selenium.firefox.FirefoxOptions; import org.testcontainers.containers.BrowserWebDriverContainer; +import org.testcontainers.junit4.TestcontainersRule; /** * @@ -13,18 +14,20 @@ public class FirefoxWebDriverContainerTest extends BaseWebDriverContainerTest { // junitRule { @Rule - public BrowserWebDriverContainer firefox = new BrowserWebDriverContainer<>() - .withCapabilities(new FirefoxOptions()) - // } - .withNetwork(NETWORK); + public TestcontainersRule> firefox = new TestcontainersRule<>( + new BrowserWebDriverContainer<>() + .withCapabilities(new FirefoxOptions()) + // } + .withNetwork(NETWORK) + ); @Before public void checkBrowserIsIndeedFirefox() { - assertBrowserNameIs(firefox, "firefox", new FirefoxOptions()); + assertBrowserNameIs(firefox.get(), "firefox", new FirefoxOptions()); } @Test public void simpleExploreTest() { - doSimpleExplore(firefox, new FirefoxOptions()); + doSimpleExplore(firefox.get(), new FirefoxOptions()); } } diff --git a/modules/selenium/src/test/java/org/testcontainers/junit/LocalServerWebDriverContainerTest.java b/modules/selenium/src/test/java/org/testcontainers/junit/LocalServerWebDriverContainerTest.java index 8d29cb57310..f2b9fe55399 100644 --- a/modules/selenium/src/test/java/org/testcontainers/junit/LocalServerWebDriverContainerTest.java +++ b/modules/selenium/src/test/java/org/testcontainers/junit/LocalServerWebDriverContainerTest.java @@ -11,6 +11,7 @@ import org.openqa.selenium.remote.RemoteWebDriver; import org.testcontainers.Testcontainers; import org.testcontainers.containers.BrowserWebDriverContainer; +import org.testcontainers.junit4.TestcontainersRule; import static org.assertj.core.api.Assertions.assertThat; @@ -21,9 +22,9 @@ public class LocalServerWebDriverContainerTest { @Rule - public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer<>() - .withAccessToHost(true) - .withCapabilities(new ChromeOptions()); + public TestcontainersRule> chrome = new TestcontainersRule<>( + new BrowserWebDriverContainer<>().withAccessToHost(true).withCapabilities(new ChromeOptions()) + ); private int localPort; @@ -44,7 +45,7 @@ public void setupLocalServer() throws Exception { @Test public void testConnection() { // getWebDriver { - RemoteWebDriver driver = new RemoteWebDriver(chrome.getSeleniumAddress(), new ChromeOptions()); + RemoteWebDriver driver = new RemoteWebDriver(chrome.get().getSeleniumAddress(), new ChromeOptions()); // } // Construct a URL that the browser container can access 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 9f0d9035f44..e85c99dc0bf 100644 --- a/modules/selenium/src/test/java/org/testcontainers/junit/SpecificImageNameWebDriverContainerTest.java +++ b/modules/selenium/src/test/java/org/testcontainers/junit/SpecificImageNameWebDriverContainerTest.java @@ -4,6 +4,7 @@ import org.junit.Test; import org.openqa.selenium.firefox.FirefoxOptions; import org.testcontainers.containers.BrowserWebDriverContainer; +import org.testcontainers.junit4.TestcontainersRule; import org.testcontainers.utility.DockerImageName; public class SpecificImageNameWebDriverContainerTest extends BaseWebDriverContainerTest { @@ -11,12 +12,12 @@ public class SpecificImageNameWebDriverContainerTest extends BaseWebDriverContai private static final DockerImageName FIREFOX_IMAGE = DockerImageName.parse("selenium/standalone-firefox:4.10.0"); @Rule - public BrowserWebDriverContainer firefox = new BrowserWebDriverContainer<>(FIREFOX_IMAGE) - .withCapabilities(new FirefoxOptions()) - .withNetwork(NETWORK); + public TestcontainersRule> firefox = new TestcontainersRule<>( + new BrowserWebDriverContainer<>(FIREFOX_IMAGE).withCapabilities(new FirefoxOptions()).withNetwork(NETWORK) + ); @Test public void simpleExploreTest() { - doSimpleExplore(firefox, new FirefoxOptions()); + doSimpleExplore(firefox.get(), new FirefoxOptions()); } } diff --git a/modules/solace/build.gradle b/modules/solace/build.gradle index fb83eede28c..e9ab9c686ef 100644 --- a/modules/solace/build.gradle +++ b/modules/solace/build.gradle @@ -5,6 +5,7 @@ dependencies { shaded 'org.awaitility:awaitility:4.2.0' + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'com.solacesystems:sol-jcsmp:10.24.1' testImplementation 'org.apache.qpid:qpid-jms-client:0.61.0' diff --git a/modules/solr/build.gradle b/modules/solr/build.gradle index d8ff7aeba39..da520f86b8f 100644 --- a/modules/solr/build.gradle +++ b/modules/solr/build.gradle @@ -5,6 +5,7 @@ dependencies { // TODO use JDK's HTTP client and/or Apache HttpClient5 shaded 'com.squareup.okhttp3:okhttp:4.12.0' + testImplementation 'junit:junit:4.13.2' testImplementation 'org.apache.solr:solr-solrj:8.11.3' testImplementation 'org.assertj:assertj-core:3.26.3' } diff --git a/modules/timeplus/build.gradle b/modules/timeplus/build.gradle index 007b46e23e4..02b56d1a4b3 100644 --- a/modules/timeplus/build.gradle +++ b/modules/timeplus/build.gradle @@ -5,6 +5,7 @@ dependencies { api project(':jdbc') testImplementation project(':jdbc-test') + testImplementation 'junit:junit:4.13.2' testRuntimeOnly 'com.timeplus:timeplus-native-jdbc:2.0.5' testImplementation 'org.assertj:assertj-core:3.26.3' } diff --git a/modules/toxiproxy/build.gradle b/modules/toxiproxy/build.gradle index 211d5e38ae3..e951a42efa5 100644 --- a/modules/toxiproxy/build.gradle +++ b/modules/toxiproxy/build.gradle @@ -4,6 +4,8 @@ dependencies { api project(':testcontainers') api 'eu.rekawek.toxiproxy:toxiproxy-java:2.1.7' + testImplementation project(':junit4') + testImplementation 'junit:junit:4.13.2' testImplementation 'redis.clients:jedis:5.1.5' testImplementation 'org.assertj:assertj-core:3.26.3' } 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 bb941640055..64f0180eae3 100644 --- a/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java +++ b/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java @@ -5,6 +5,7 @@ import eu.rekawek.toxiproxy.model.ToxicDirection; import org.junit.Rule; import org.junit.Test; +import org.testcontainers.junit4.TestcontainersRule; import redis.clients.jedis.Jedis; import redis.clients.jedis.exceptions.JedisConnectionException; @@ -23,25 +24,29 @@ public class ToxiproxyTest { // creatingProxy { // Create a common docker network so that containers can communicate @Rule - public Network network = Network.newNetwork(); + public TestcontainersRule network = new TestcontainersRule<>(Network.newNetwork()); // The target container - this could be anything @Rule - public GenericContainer redis = new GenericContainer<>("redis:6-alpine") + public TestcontainersRule> redis = new TestcontainersRule<>( + new GenericContainer<>("redis:6-alpine") .withExposedPorts(6379) - .withNetwork(network) - .withNetworkAliases("redis"); + .withNetwork(network.get()) + .withNetworkAliases("redis") + ); // Toxiproxy container, which will be used as a TCP proxy @Rule - public ToxiproxyContainer toxiproxy = new ToxiproxyContainer("ghcr.io/shopify/toxiproxy:2.5.0") - .withNetwork(network); + public TestcontainersRule toxiproxy = new TestcontainersRule<>( + new ToxiproxyContainer("ghcr.io/shopify/toxiproxy:2.5.0") + .withNetwork(network.get()) + ); // } // spotless:on @Test public void testDirect() { - final Jedis jedis = createJedis(redis.getHost(), redis.getFirstMappedPort()); + final Jedis jedis = createJedis(redis.get().getHost(), redis.get().getFirstMappedPort()); jedis.set("somekey", "somevalue"); final String s = jedis.get("somekey"); @@ -51,13 +56,16 @@ public void testDirect() { @Test public void testLatencyViaProxy() throws IOException { // obtainProxyObject { - final ToxiproxyClient toxiproxyClient = new ToxiproxyClient(toxiproxy.getHost(), toxiproxy.getControlPort()); + final ToxiproxyClient toxiproxyClient = new ToxiproxyClient( + toxiproxy.get().getHost(), + toxiproxy.get().getControlPort() + ); final Proxy proxy = toxiproxyClient.createProxy("redis", "0.0.0.0:8666", "redis:6379"); // } // obtainProxiedHostAndPortForHostMachine { - final String ipAddressViaToxiproxy = toxiproxy.getHost(); - final int portViaToxiproxy = toxiproxy.getMappedPort(8666); + final String ipAddressViaToxiproxy = toxiproxy.get().getHost(); + final int portViaToxiproxy = toxiproxy.get().getMappedPort(8666); // } final Jedis jedis = createJedis(ipAddressViaToxiproxy, portViaToxiproxy); @@ -79,9 +87,12 @@ public void testLatencyViaProxy() throws IOException { @Test public void testConnectionCut() throws IOException { - final ToxiproxyClient toxiproxyClient = new ToxiproxyClient(toxiproxy.getHost(), toxiproxy.getControlPort()); + final ToxiproxyClient toxiproxyClient = new ToxiproxyClient( + toxiproxy.get().getHost(), + toxiproxy.get().getControlPort() + ); final Proxy proxy = toxiproxyClient.createProxy("redis", "0.0.0.0:8666", "redis:6379"); - final Jedis jedis = createJedis(toxiproxy.getHost(), toxiproxy.getMappedPort(8666)); + final Jedis jedis = createJedis(toxiproxy.get().getHost(), toxiproxy.get().getMappedPort(8666)); jedis.set("somekey", "somevalue"); assertThat(jedis.get("somekey")) @@ -117,20 +128,20 @@ public void testMultipleProxiesCanBeCreated() throws IOException { try ( GenericContainer secondRedis = new GenericContainer<>("redis:6-alpine") .withExposedPorts(6379) - .withNetwork(network) + .withNetwork(network.get()) .withNetworkAliases("redis2") ) { secondRedis.start(); final ToxiproxyClient toxiproxyClient = new ToxiproxyClient( - toxiproxy.getHost(), - toxiproxy.getControlPort() + toxiproxy.get().getHost(), + toxiproxy.get().getControlPort() ); final Proxy firstProxy = toxiproxyClient.createProxy("redis1", "0.0.0.0:8666", "redis:6379"); toxiproxyClient.createProxy("redis2", "0.0.0.0:8667", "redis2:6379"); - final Jedis firstJedis = createJedis(toxiproxy.getHost(), toxiproxy.getMappedPort(8666)); - final Jedis secondJedis = createJedis(toxiproxy.getHost(), toxiproxy.getMappedPort(8667)); + final Jedis firstJedis = createJedis(toxiproxy.get().getHost(), toxiproxy.get().getMappedPort(8666)); + final Jedis secondJedis = createJedis(toxiproxy.get().getHost(), toxiproxy.get().getMappedPort(8667)); firstJedis.set("somekey", "somevalue"); secondJedis.set("somekey", "somevalue"); @@ -152,27 +163,27 @@ public void testMultipleProxiesCanBeCreated() throws IOException { @Test public void testOriginalAndMappedPorts() { - final ToxiproxyContainer.ContainerProxy proxy = toxiproxy.getProxy("hostname", 7070); + final ToxiproxyContainer.ContainerProxy proxy = toxiproxy.get().getProxy("hostname", 7070); final int portViaToxiproxy = proxy.getOriginalProxyPort(); assertThat(portViaToxiproxy).as("original port is correct").isEqualTo(8666); - final ToxiproxyContainer.ContainerProxy proxy1 = toxiproxy.getProxy("hostname1", 8080); + final ToxiproxyContainer.ContainerProxy proxy1 = toxiproxy.get().getProxy("hostname1", 8080); assertThat(proxy1.getOriginalProxyPort()).as("original port is correct").isEqualTo(8667); assertThat(proxy1.getProxyPort()) .as("mapped port is correct") - .isEqualTo(toxiproxy.getMappedPort(proxy1.getOriginalProxyPort())); + .isEqualTo(toxiproxy.get().getMappedPort(proxy1.getOriginalProxyPort())); - final ToxiproxyContainer.ContainerProxy proxy2 = toxiproxy.getProxy("hostname2", 9090); + final ToxiproxyContainer.ContainerProxy proxy2 = toxiproxy.get().getProxy("hostname2", 9090); assertThat(proxy2.getOriginalProxyPort()).as("original port is correct").isEqualTo(8668); assertThat(proxy2.getProxyPort()) .as("mapped port is correct") - .isEqualTo(toxiproxy.getMappedPort(proxy2.getOriginalProxyPort())); + .isEqualTo(toxiproxy.get().getMappedPort(proxy2.getOriginalProxyPort())); } @Test public void testProxyName() { - final ToxiproxyContainer.ContainerProxy proxy = toxiproxy.getProxy("hostname", 7070); + final ToxiproxyContainer.ContainerProxy proxy = toxiproxy.get().getProxy("hostname", 7070); assertThat(proxy.getName()).as("proxy name is hostname and port").isEqualTo("hostname:7070"); } diff --git a/modules/typesense/build.gradle b/modules/typesense/build.gradle index 1a639ba2677..a28a035de05 100644 --- a/modules/typesense/build.gradle +++ b/modules/typesense/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: Typesense" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'org.typesense:typesense-java:0.9.0' } diff --git a/modules/vault/build.gradle b/modules/vault/build.gradle index 263dff37fbf..c6e1791d2a3 100644 --- a/modules/vault/build.gradle +++ b/modules/vault/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: Vault" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'com.bettercloud:vault-java-driver:5.1.0' testImplementation 'io.rest-assured:rest-assured:5.5.0' testImplementation 'org.assertj:assertj-core:3.26.3' diff --git a/modules/weaviate/build.gradle b/modules/weaviate/build.gradle index 1281fa120d0..8c8e61ddb74 100644 --- a/modules/weaviate/build.gradle +++ b/modules/weaviate/build.gradle @@ -3,6 +3,7 @@ description = "Testcontainers :: Weaviate" dependencies { api project(':testcontainers') + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'io.weaviate:client:4.8.3' }