diff --git a/.github/workflows/ci-examples.yml b/.github/workflows/ci-examples.yml index d81a4ffb509..4f91341a4a6 100644 --- a/.github/workflows/ci-examples.yml +++ b/.github/workflows/ci-examples.yml @@ -20,11 +20,10 @@ jobs: java-version: '1.8' - name: Cache Gradle Home files uses: actions/cache@v1 + continue-on-error: true with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-home-testmatrix-examples-${{ hashFiles('**/*.gradle') }} - restore-keys: | - ${{ runner.os }}-gradle-home-testmatrix-examples- - id: set-matrix working-directory: ./examples/ env: @@ -48,11 +47,10 @@ jobs: java-version: '1.8' - name: Cache Gradle Home files uses: actions/cache@v1 + continue-on-error: true with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-home-examples-${{matrix.gradle_args}}_check-${{ hashFiles('**/*.gradle') }} - restore-keys: | - ${{ runner.os }}-gradle-home-examples-${{matrix.gradle_args}}_check- - name: Clear existing docker image cache run: docker image prune -af - name: Build and test Examples with Gradle (${{matrix.gradle_args}}) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2b5a37a3405..df38f3b8a4f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,8 +23,6 @@ jobs: with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-home-testmatrix-${{ hashFiles('**/*.gradle') }} - restore-keys: | - ${{ runner.os }}-gradle-home-testmatrix- - id: set-matrix env: # Since we override the tests executor, @@ -51,8 +49,6 @@ jobs: with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-home-${{matrix.gradle_args}}_check-${{ hashFiles('**/*.gradle') }} - restore-keys: | - ${{ runner.os }}-gradle-home-${{matrix.gradle_args}}_check- - name: Clear existing docker image cache run: docker image prune -af - name: Build and test with Gradle (${{matrix.gradle_args}}) diff --git a/.github/workflows/update-gradle-wrapper.yml b/.github/workflows/update-gradle-wrapper.yml new file mode 100644 index 00000000000..f3a01949324 --- /dev/null +++ b/.github/workflows/update-gradle-wrapper.yml @@ -0,0 +1,20 @@ +name: Update Gradle Wrapper + +on: + schedule: + - cron: "0 0 * * *" + +jobs: + update-gradle-wrapper: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Update Gradle Wrapper + uses: gradle-update/update-gradle-wrapper-action@74a035c + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + labels: dependencies + + - uses: gradle/wrapper-validation-action@e2c57ac diff --git a/core/build.gradle b/core/build.gradle index 37595c18e7c..e043313ac38 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -192,11 +192,11 @@ dependencies { compile 'com.github.docker-java:docker-java-transport-zerodep:3.2.5' - shaded "org.yaml:snakeyaml:1.25" + shaded "org.yaml:snakeyaml:1.27" shaded 'org.glassfish.main.external:trilead-ssh2-repackaged:4.1.2' - shaded 'org.zeroturnaround:zt-exec:1.10', { + shaded 'org.zeroturnaround:zt-exec:1.12', { exclude(group: 'org.slf4j') } @@ -205,13 +205,13 @@ dependencies { testCompile 'com.rabbitmq:amqp-client:5.9.0' testCompile 'org.mongodb:mongo-java-driver:3.12.7' - testCompile ('org.mockito:mockito-core:3.5.11') { + testCompile ('org.mockito:mockito-core:3.5.13') { exclude(module: 'hamcrest-core') } // Synthetic JAR used for MountableFileTest and DirectoryTarResourceTest testCompile files('testlib/repo/fakejar/fakejar/0/fakejar-0.jar') - testCompile 'org.assertj:assertj-core:3.17.1' + testCompile 'org.assertj:assertj-core:3.17.2' testCompile project(':test-support') jarFileTestCompileOnly "org.projectlombok:lombok:${lombok.version}" diff --git a/core/src/main/java/org/testcontainers/dockerclient/DockerMachineClientProviderStrategy.java b/core/src/main/java/org/testcontainers/dockerclient/DockerMachineClientProviderStrategy.java index 2b0454c1ee6..4de508ea808 100644 --- a/core/src/main/java/org/testcontainers/dockerclient/DockerMachineClientProviderStrategy.java +++ b/core/src/main/java/org/testcontainers/dockerclient/DockerMachineClientProviderStrategy.java @@ -37,12 +37,12 @@ private TransportConfig resolveTransportConfig() throws InvalidConfigurationExce DockerMachineClient.instance().ensureMachineRunning(machineName); - String dockerDaemonIpAddress = DockerMachineClient.instance().getDockerDaemonIpAddress(machineName); + String dockerDaemonUrl = DockerMachineClient.instance().getDockerDaemonUrl(machineName); - log.info("Docker daemon IP address for docker machine {} is {}", machineName, dockerDaemonIpAddress); + log.info("Docker daemon URL for docker machine {} is {}", machineName, dockerDaemonUrl); return TransportConfig.builder() - .dockerHost(URI.create("tcp://" + dockerDaemonIpAddress + ":2376")) + .dockerHost(URI.create(dockerDaemonUrl)) .sslConfig( new LocalDirectorySSLConfig( Paths.get(System.getProperty("user.home") + "/.docker/machine/certs/").toString() diff --git a/core/src/main/java/org/testcontainers/utility/DockerMachineClient.java b/core/src/main/java/org/testcontainers/utility/DockerMachineClient.java index fe12e9f541d..021baf270d9 100644 --- a/core/src/main/java/org/testcontainers/utility/DockerMachineClient.java +++ b/core/src/main/java/org/testcontainers/utility/DockerMachineClient.java @@ -79,10 +79,18 @@ public void ensureMachineRunning(@NonNull String machineName) { } } + /** + * @deprecated Use getDockerDaemonUrl(@NonNull String machineName) for connection to docker-machine + */ + @Deprecated public String getDockerDaemonIpAddress(@NonNull String machineName) { return runShellCommand(executableName, "ip", machineName); } + public String getDockerDaemonUrl(@NonNull String machineName) { + return runShellCommand(executableName, "url", machineName); + } + public boolean isMachineRunning(String machineName) { String status = runShellCommand("docker-machine", "status", machineName); return status.trim().equalsIgnoreCase("running"); diff --git a/core/src/main/java/org/testcontainers/utility/Versioning.java b/core/src/main/java/org/testcontainers/utility/Versioning.java index 8944b3f0ba6..84dcf46274e 100644 --- a/core/src/main/java/org/testcontainers/utility/Versioning.java +++ b/core/src/main/java/org/testcontainers/utility/Versioning.java @@ -24,12 +24,12 @@ public boolean isValid() { @Override public String getSeparator() { - return ""; + return ":"; } @Override public String toString() { - return ""; + return "latest"; } @Override diff --git a/core/src/test/java/org/testcontainers/dockerclient/AmbiguousImagePullTest.java b/core/src/test/java/org/testcontainers/dockerclient/AmbiguousImagePullTest.java new file mode 100644 index 00000000000..5d2c42ed1b2 --- /dev/null +++ b/core/src/test/java/org/testcontainers/dockerclient/AmbiguousImagePullTest.java @@ -0,0 +1,34 @@ +package org.testcontainers.dockerclient; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.model.Image; +import org.junit.Test; +import org.testcontainers.DockerClientFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.startupcheck.OneShotStartupCheckStrategy; +import org.testcontainers.utility.DockerImageName; + +import java.util.List; + +public class AmbiguousImagePullTest { + + @Test(timeout = 30_000) + public void testNotUsingParse() { + DockerClient client = DockerClientFactory.instance().client(); + List alpineImages = client.listImagesCmd() + .withImageNameFilter("alpine:latest") + .exec(); + for (Image alpineImage : alpineImages) { + client.removeImageCmd(alpineImage.getId()).exec(); + } + + try ( + final GenericContainer container = new GenericContainer<>(DockerImageName.parse("alpine")) + .withCommand("/bin/sh", "-c", "sleep 0") + .withStartupCheckStrategy(new OneShotStartupCheckStrategy()) + ) { + container.start(); + // do nothing other than start and stop + } + } +} diff --git a/core/src/test/java/org/testcontainers/utility/DockerImageNameTest.java b/core/src/test/java/org/testcontainers/utility/DockerImageNameTest.java index 34575f2b4b9..e06407fbf56 100644 --- a/core/src/test/java/org/testcontainers/utility/DockerImageNameTest.java +++ b/core/src/test/java/org/testcontainers/utility/DockerImageNameTest.java @@ -112,7 +112,7 @@ public void testParsing() { canonicalName = unversionedPart + versionSeparator + version; } else { combined = unversionedPart; - canonicalName = unversionedPart; + canonicalName = unversionedPart + ":latest"; } VisibleAssertions.context("For " + combined); @@ -124,7 +124,7 @@ public void testParsing() { if (version != null) { assertEquals(combined + " has version part: " + version, version, imageName.getVersionPart()); } else { - assertEquals(combined + " has no version specified", "", imageName.getVersionPart()); + assertEquals(combined + " has automatic 'latest' version specified", "latest", imageName.getVersionPart()); } assertEquals(combined + " has canonical name: " + canonicalName, canonicalName, imageName.asCanonicalNameString()); 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 f49e6a26565..73338ba38ee 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/CmdModifierTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/CmdModifierTest.java @@ -19,8 +19,8 @@ public class CmdModifierTest { // } // memory { - private long memoryInBytes = 8 * 1024 * 1024; - private long memorySwapInBytes = 12 * 1024 * 1024; + private long memoryInBytes = 32 * 1024 * 1024; + private long memorySwapInBytes = 64 * 1024 * 1024; @Rule public GenericContainer memoryLimitedRedis = new GenericContainer<>(DockerImageName.parse("redis:3.0.2")) @@ -40,6 +40,6 @@ public void testHostnameModified() throws IOException, InterruptedException { @Test public void testMemoryLimitModified() throws IOException, InterruptedException { final Container.ExecResult execResult = memoryLimitedRedis.execInContainer("cat", "/sys/fs/cgroup/memory/memory.limit_in_bytes"); - assertEquals("8388608", execResult.getStdout().trim()); + assertEquals(String.valueOf(memoryInBytes), execResult.getStdout().trim()); } } 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 329fd8d8e19..de2b56c6a63 100644 --- a/docs/examples/junit4/generic/src/test/java/generic/MultiplePortsExposedTest.java +++ b/docs/examples/junit4/generic/src/test/java/generic/MultiplePortsExposedTest.java @@ -1,5 +1,7 @@ package generic; +import static org.slf4j.LoggerFactory.getLogger; + import org.junit.Rule; import org.junit.Test; import org.slf4j.Logger; @@ -7,23 +9,21 @@ import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.utility.DockerImageName; -import static org.slf4j.LoggerFactory.getLogger; - public class MultiplePortsExposedTest { private static final Logger log = getLogger(MultiplePortsExposedTest.class); @Rule // rule { - public GenericContainer container = new GenericContainer(DockerImageName.parse("orientdb:3.0.13")) - .withExposedPorts(2424, 2480) + public GenericContainer container = new GenericContainer<>(DockerImageName.parse("testcontainers/helloworld:1.1.0")) + .withExposedPorts(8080, 8081) .withLogConsumer(new Slf4jLogConsumer(log)); // } @Test public void fetchPortsByNumber() { - Integer firstMappedPort = container.getMappedPort(2424); - Integer secondMappedPort = container.getMappedPort(2480); + Integer firstMappedPort = container.getMappedPort(8080); + Integer secondMappedPort = container.getMappedPort(8081); } @Test @@ -39,6 +39,6 @@ public void getHostOnly() { @Test public void getHostAndMappedPort() { String address = - container.getHost() + ":" + container.getMappedPort(2424); + container.getHost() + ":" + container.getMappedPort(8080); } } diff --git a/docs/modules/gcloud.md b/docs/modules/gcloud.md new file mode 100644 index 00000000000..3400ad881a9 --- /dev/null +++ b/docs/modules/gcloud.md @@ -0,0 +1,44 @@ +# GCloud Module + +!!! note + This module is INCUBATING. While it is ready for use and operational in the current version of Testcontainers, it is possible that it may receive breaking changes in the future. See [our contributing guidelines](/contributing/#incubating-modules) for more information on our incubating modules policy. + +Testcontainers module for the Google's [Cloud SDK](https://cloud.google.com/sdk/). + +Currently, the module supports `Datastore`, `Firestore`, `Pub/Sub` and `Spanner` emulators. In order to use it, you should use the following classes: + +* DatastoreEmulatorContainer +* FirestoreEmulatorContainer +* PubSubEmulatorContainer +* SpannerEmulatorContainer + +## Usage example + +Running GCloud as a stand-in for Google Datastore during a test: + + +[Creating a Datastore container](../../modules/gcloud/src/test/java/org/testcontainers/containers/DatastoreEmulatorContainerTest.java) inside_block:creatingDatastoreEmulatorContainer + + +And how to start it: + + +[Starting a Datastore container](../../modules/gcloud/src/test/java/org/testcontainers/containers/DatastoreEmulatorContainerTest.java) inside_block:startingDatastoreEmulatorContainer + + +## Adding this module to your project dependencies + +Add the following dependency to your `pom.xml`/`build.gradle` file: + +```groovy tab='Gradle' +testCompile "org.testcontainers:gcloud:{{latest_version}}" +``` + +```xml tab='Maven' + + org.testcontainers + gcloud + {{latest_version}} + test + +``` diff --git a/examples/cucumber/build.gradle b/examples/cucumber/build.gradle index 318ed51f24c..57104731c7e 100644 --- a/examples/cucumber/build.gradle +++ b/examples/cucumber/build.gradle @@ -10,7 +10,7 @@ dependencies { implementation 'org.seleniumhq.selenium:selenium-remote-driver:3.141.59' implementation 'org.seleniumhq.selenium:selenium-firefox-driver:3.141.59' implementation 'org.seleniumhq.selenium:selenium-chrome-driver:3.141.59' - testImplementation 'io.cucumber:cucumber-java:6.6.0' - testImplementation 'io.cucumber:cucumber-junit:6.7.0' + testImplementation 'io.cucumber:cucumber-java:6.8.1' + testImplementation 'io.cucumber:cucumber-junit:6.8.1' testImplementation 'org.testcontainers:selenium' } diff --git a/examples/disque-job-queue/build.gradle b/examples/disque-job-queue/build.gradle index fb8413bdec8..c5e191f4f94 100644 --- a/examples/disque-job-queue/build.gradle +++ b/examples/disque-job-queue/build.gradle @@ -7,8 +7,8 @@ repositories { } dependencies { - compileOnly "org.projectlombok:lombok:1.18.12" - annotationProcessor "org.projectlombok:lombok:1.18.10" + compileOnly "org.projectlombok:lombok:1.18.14" + annotationProcessor "org.projectlombok:lombok:1.18.14" implementation 'biz.paluch.redis:spinach:0.3' implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.google.guava:guava:23.0' diff --git a/examples/kafka-cluster/build.gradle b/examples/kafka-cluster/build.gradle index 0da1152f44a..2817a5e5f26 100644 --- a/examples/kafka-cluster/build.gradle +++ b/examples/kafka-cluster/build.gradle @@ -13,5 +13,5 @@ dependencies { compile 'org.apache.kafka:kafka-clients:2.3.1' testCompile 'org.assertj:assertj-core:3.14.0' testCompile 'com.google.guava:guava:23.0' - testCompile 'org.slf4j:slf4j-simple:+' + testCompile 'org.slf4j:slf4j-simple:1.7.30' } diff --git a/examples/linked-container/build.gradle b/examples/linked-container/build.gradle index eac2c59df4a..5c4c473becb 100644 --- a/examples/linked-container/build.gradle +++ b/examples/linked-container/build.gradle @@ -9,7 +9,7 @@ dependencies { compileOnly 'org.slf4j:slf4j-api:1.7.30' implementation 'com.squareup.okhttp3:okhttp:4.9.0' implementation 'org.json:json:20180813' - testImplementation 'org.postgresql:postgresql:42.2.16' + testImplementation 'org.postgresql:postgresql:42.2.17' testImplementation 'ch.qos.logback:logback-classic:1.2.3' testImplementation 'org.testcontainers:postgresql' } diff --git a/examples/mongodb-container/build.gradle b/examples/mongodb-container/build.gradle index c09cb033489..57b578a1607 100644 --- a/examples/mongodb-container/build.gradle +++ b/examples/mongodb-container/build.gradle @@ -8,6 +8,6 @@ repositories { dependencies { testImplementation 'org.testcontainers:testcontainers' - testImplementation 'junit:junit:4.13' + testImplementation 'junit:junit:4.13.1' testCompileClasspath 'org.jetbrains:annotations:20.1.0' } diff --git a/examples/redis-backed-cache-testng/build.gradle b/examples/redis-backed-cache-testng/build.gradle index 62f7de6dcf8..6ef351764f5 100644 --- a/examples/redis-backed-cache-testng/build.gradle +++ b/examples/redis-backed-cache-testng/build.gradle @@ -13,7 +13,7 @@ dependencies { implementation 'com.google.guava:guava:23.0' testImplementation 'org.testcontainers:testcontainers' testImplementation 'ch.qos.logback:logback-classic:1.2.3' - testImplementation 'org.testng:testng:7.2.0' + testImplementation 'org.testng:testng:7.3.0' } test { diff --git a/examples/redis-backed-cache/build.gradle b/examples/redis-backed-cache/build.gradle index 258c98fb107..b0b6865aea7 100644 --- a/examples/redis-backed-cache/build.gradle +++ b/examples/redis-backed-cache/build.gradle @@ -12,6 +12,6 @@ dependencies { implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.google.guava:guava:23.0' testImplementation 'org.testcontainers:testcontainers' - testImplementation 'junit:junit:4.13' + testImplementation 'junit:junit:4.13.1' testImplementation 'ch.qos.logback:logback-classic:1.2.3' } diff --git a/examples/selenium-container/build.gradle b/examples/selenium-container/build.gradle index eb9c2d9ce3a..2dca03f4004 100644 --- a/examples/selenium-container/build.gradle +++ b/examples/selenium-container/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.springframework.boot' version '2.3.3.RELEASE' + id 'org.springframework.boot' version '2.3.4.RELEASE' } apply plugin: 'io.spring.dependency-management' diff --git a/examples/solr-container/build.gradle b/examples/solr-container/build.gradle index 52fa54f1fc5..5a8973cab27 100644 --- a/examples/solr-container/build.gradle +++ b/examples/solr-container/build.gradle @@ -7,10 +7,10 @@ repositories { } dependencies { - compileOnly "org.projectlombok:lombok:1.18.10" + compileOnly "org.projectlombok:lombok:1.18.14" annotationProcessor "org.projectlombok:lombok:1.18.10" - implementation 'org.apache.solr:solr-solrj:8.6.2' + implementation 'org.apache.solr:solr-solrj:8.6.3' testImplementation 'org.testcontainers:testcontainers' testImplementation 'org.testcontainers:solr' diff --git a/examples/spring-boot/build.gradle b/examples/spring-boot/build.gradle index d74851d8eac..75907da4c0d 100644 --- a/examples/spring-boot/build.gradle +++ b/examples/spring-boot/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.springframework.boot' version '2.3.3.RELEASE' + id 'org.springframework.boot' version '2.3.4.RELEASE' } apply plugin: 'io.spring.dependency-management' diff --git a/mkdocs.yml b/mkdocs.yml index b8372e81ed8..dfff99bb302 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -60,6 +60,7 @@ nav: - modules/databases/presto.md - modules/docker_compose.md - modules/elasticsearch.md + - modules/gcloud.md - modules/kafka.md - modules/localstack.md - modules/mockserver.md diff --git a/modules/dynalite/build.gradle b/modules/dynalite/build.gradle index 0b2e334c633..fe8fb883839 100644 --- a/modules/dynalite/build.gradle +++ b/modules/dynalite/build.gradle @@ -3,6 +3,6 @@ description = "Testcontainers :: Dynalite" dependencies { compile project(':testcontainers') - compileOnly 'com.amazonaws:aws-java-sdk-dynamodb:1.11.865' + compileOnly 'com.amazonaws:aws-java-sdk-dynamodb:1.11.880' testCompile 'com.amazonaws:aws-java-sdk-dynamodb:1.11.865' } diff --git a/modules/elasticsearch/build.gradle b/modules/elasticsearch/build.gradle index 44a5cca5963..e6de1daa7ab 100644 --- a/modules/elasticsearch/build.gradle +++ b/modules/elasticsearch/build.gradle @@ -2,6 +2,6 @@ description = "TestContainers :: elasticsearch" dependencies { compile project(':testcontainers') - testCompile "org.elasticsearch.client:elasticsearch-rest-client:7.9.1" + testCompile "org.elasticsearch.client:elasticsearch-rest-client:7.9.2" testCompile "org.elasticsearch.client:transport:6.7.1" } diff --git a/modules/gcloud/build.gradle b/modules/gcloud/build.gradle new file mode 100644 index 00000000000..a5737648a4b --- /dev/null +++ b/modules/gcloud/build.gradle @@ -0,0 +1,11 @@ +description = "Testcontainers :: GCloud" + +dependencies { + compile project(':testcontainers') + + testCompile 'com.google.cloud:google-cloud-datastore:1.102.4' + testCompile 'com.google.cloud:google-cloud-firestore:1.33.0' + testCompile 'com.google.cloud:google-cloud-pubsub:1.105.0' + testCompile 'com.google.cloud:google-cloud-spanner:1.50.0' + testCompile 'org.assertj:assertj-core:3.15.0' +} diff --git a/modules/gcloud/src/main/java/org/testcontainers/containers/DatastoreEmulatorContainer.java b/modules/gcloud/src/main/java/org/testcontainers/containers/DatastoreEmulatorContainer.java new file mode 100644 index 00000000000..fe0a9959f2d --- /dev/null +++ b/modules/gcloud/src/main/java/org/testcontainers/containers/DatastoreEmulatorContainer.java @@ -0,0 +1,38 @@ +package org.testcontainers.containers; + +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; + +/** + * A Datastore container that relies in google cloud sdk. + * + * Default port is 8081. + * + * @author Eddú Meléndez + */ +public class DatastoreEmulatorContainer extends GenericContainer { + + private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk"); + + private static final String CMD = "gcloud beta emulators datastore start --project test-project --host-port 0.0.0.0:8081"; + private static final int HTTP_PORT = 8081; + + public DatastoreEmulatorContainer(final DockerImageName dockerImageName) { + super(dockerImageName); + + dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); + + withExposedPorts(HTTP_PORT); + setWaitStrategy(Wait.forHttp("/").forStatusCode(200)); + withCommand("/bin/sh", "-c", CMD); + } + + /** + * @return a host:port pair corresponding to the address on which the emulator is + * reachable from the test host machine. Directly usable as a parameter to the + * com.google.cloud.ServiceOptions.Builder#setHost(java.lang.String) method. + */ + public String getEmulatorEndpoint() { + return getContainerIpAddress() + ":" + getMappedPort(8081); + } +} diff --git a/modules/gcloud/src/main/java/org/testcontainers/containers/FirestoreEmulatorContainer.java b/modules/gcloud/src/main/java/org/testcontainers/containers/FirestoreEmulatorContainer.java new file mode 100644 index 00000000000..6353a679130 --- /dev/null +++ b/modules/gcloud/src/main/java/org/testcontainers/containers/FirestoreEmulatorContainer.java @@ -0,0 +1,39 @@ +package org.testcontainers.containers; + +import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; +import org.testcontainers.utility.DockerImageName; + +/** + * A Firestore container that relies in google cloud sdk. + * + * Default port is 8080. + * + * @author Eddú Meléndez + */ +public class FirestoreEmulatorContainer extends GenericContainer { + + private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk"); + + private static final String CMD = "gcloud beta emulators firestore start --host-port 0.0.0.0:8080"; + private static final int PORT = 8080; + + public FirestoreEmulatorContainer(final DockerImageName dockerImageName) { + super(dockerImageName); + + dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); + + withExposedPorts(PORT); + setWaitStrategy(new LogMessageWaitStrategy() + .withRegEx("(?s).*running.*$")); + withCommand("/bin/sh", "-c", CMD); + } + + /** + * @return a host:port pair corresponding to the address on which the emulator is + * reachable from the test host machine. Directly usable as a parameter to the + * com.google.cloud.ServiceOptions.Builder#setHost(java.lang.String) method. + */ + public String getEmulatorEndpoint() { + return getContainerIpAddress() + ":" + getMappedPort(8080); + } +} diff --git a/modules/gcloud/src/main/java/org/testcontainers/containers/PubSubEmulatorContainer.java b/modules/gcloud/src/main/java/org/testcontainers/containers/PubSubEmulatorContainer.java new file mode 100644 index 00000000000..90d77c837cf --- /dev/null +++ b/modules/gcloud/src/main/java/org/testcontainers/containers/PubSubEmulatorContainer.java @@ -0,0 +1,39 @@ +package org.testcontainers.containers; + +import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; +import org.testcontainers.utility.DockerImageName; + +/** + * A PubSub container that relies in google cloud sdk. + * + * Default port is 8085. + * + * @author Eddú Meléndez + */ +public class PubSubEmulatorContainer extends GenericContainer { + + private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk"); + + private static final String CMD = "gcloud beta emulators pubsub start --host-port 0.0.0.0:8085"; + private static final int PORT = 8085; + + public PubSubEmulatorContainer(final DockerImageName dockerImageName) { + super(dockerImageName); + + dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); + + withExposedPorts(8085); + setWaitStrategy(new LogMessageWaitStrategy() + .withRegEx("(?s).*started.*$")); + withCommand("/bin/sh", "-c", CMD); + } + + /** + * @return a host:port pair corresponding to the address on which the emulator is + * reachable from the test host machine. Directly usable as a parameter to the + * io.grpc.ManagedChannelBuilder#forTarget(java.lang.String) method. + */ + public String getEmulatorEndpoint() { + return getContainerIpAddress() + ":" + getMappedPort(PORT); + } +} diff --git a/modules/gcloud/src/main/java/org/testcontainers/containers/SpannerEmulatorContainer.java b/modules/gcloud/src/main/java/org/testcontainers/containers/SpannerEmulatorContainer.java new file mode 100644 index 00000000000..8603b1f3437 --- /dev/null +++ b/modules/gcloud/src/main/java/org/testcontainers/containers/SpannerEmulatorContainer.java @@ -0,0 +1,44 @@ +package org.testcontainers.containers; + +import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; +import org.testcontainers.utility.DockerImageName; + +/** + * A Spanner container. Default ports: 9010 for GRPC and 9020 for HTTP. + * + * @author Eddú Meléndez + */ +public class SpannerEmulatorContainer extends GenericContainer { + + private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("gcr.io/cloud-spanner-emulator/emulator"); + + private static final int GRPC_PORT = 9010; + private static final int HTTP_PORT = 9020; + + public SpannerEmulatorContainer(final DockerImageName dockerImageName) { + super(dockerImageName); + + dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); + + withExposedPorts(GRPC_PORT, HTTP_PORT); + setWaitStrategy(new LogMessageWaitStrategy() + .withRegEx(".*Cloud Spanner emulator running\\..*")); + } + + /** + * @return a host:port pair corresponding to the address on which the emulator's + * gRPC endpoint is reachable from the test host machine. Directly usable as a parameter to the + * com.google.cloud.spanner.SpannerOptions.Builder#setEmulatorHost(java.lang.String) method. + */ + public String getEmulatorGrpcEndpoint() { + return getContainerIpAddress() + ":" + getMappedPort(GRPC_PORT); + } + + /** + * @return a host:port pair corresponding to the address on which the emulator's + * HTTP REST endpoint is reachable from the test host machine. + */ + public String getEmulatorHttpEndpoint() { + return getContainerIpAddress() + ":" + getMappedPort(HTTP_PORT); + } +} diff --git a/modules/gcloud/src/test/java/org/testcontainers/containers/DatastoreEmulatorContainerTest.java b/modules/gcloud/src/test/java/org/testcontainers/containers/DatastoreEmulatorContainerTest.java new file mode 100644 index 00000000000..4709ed1bbd6 --- /dev/null +++ b/modules/gcloud/src/test/java/org/testcontainers/containers/DatastoreEmulatorContainerTest.java @@ -0,0 +1,43 @@ +package org.testcontainers.containers; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.cloud.NoCredentials; +import com.google.cloud.ServiceOptions; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.Key; +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.utility.DockerImageName; + +public class DatastoreEmulatorContainerTest { + + @Rule + // creatingDatastoreEmulatorContainer { + public DatastoreEmulatorContainer emulator = new DatastoreEmulatorContainer( + DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk:313.0.0") + ); + // } + + // startingDatastoreEmulatorContainer { + @Test + public void testSimple() { + DatastoreOptions options = DatastoreOptions.newBuilder() + .setHost(emulator.getEmulatorEndpoint()) + .setCredentials(NoCredentials.getInstance()) + .setRetrySettings(ServiceOptions.getNoRetrySettings()) + .setProjectId("test-project") + .build(); + Datastore datastore = options.getService(); + + Key key = datastore.newKeyFactory().setKind("Task").newKey("sample"); + Entity entity = Entity.newBuilder(key).set("description", "my description").build(); + datastore.put(entity); + + assertThat(datastore.get(key).getString("description")).isEqualTo("my description"); + } + // } + +} diff --git a/modules/gcloud/src/test/java/org/testcontainers/containers/FirestoreEmulatorContainerTest.java b/modules/gcloud/src/test/java/org/testcontainers/containers/FirestoreEmulatorContainerTest.java new file mode 100644 index 00000000000..766ce657bf0 --- /dev/null +++ b/modules/gcloud/src/test/java/org/testcontainers/containers/FirestoreEmulatorContainerTest.java @@ -0,0 +1,48 @@ +package org.testcontainers.containers; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.api.core.ApiFuture; +import com.google.cloud.NoCredentials; +import com.google.cloud.firestore.CollectionReference; +import com.google.cloud.firestore.DocumentReference; +import com.google.cloud.firestore.Firestore; +import com.google.cloud.firestore.FirestoreOptions; +import com.google.cloud.firestore.QuerySnapshot; +import com.google.cloud.firestore.WriteResult; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.utility.DockerImageName; + +public class FirestoreEmulatorContainerTest { + + @Rule + public FirestoreEmulatorContainer emulator = new FirestoreEmulatorContainer(DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk:313.0.0")); + + @Test + public void testSimple() throws ExecutionException, InterruptedException { + FirestoreOptions options = FirestoreOptions.getDefaultInstance().toBuilder() + .setHost(emulator.getEmulatorEndpoint()) + .setCredentials(NoCredentials.getInstance()) + .setProjectId("test-project") + .build(); + Firestore firestore = options.getService(); + + CollectionReference users = firestore.collection("users"); + DocumentReference docRef = users.document("alovelace"); + Map data = new HashMap<>(); + data.put("first", "Ada"); + data.put("last", "Lovelace"); + ApiFuture result = docRef.set(data); + result.get(); + + ApiFuture query = users.get(); + QuerySnapshot querySnapshot = query.get(); + + assertThat(querySnapshot.getDocuments().get(0).getData()).containsEntry("first", "Ada"); + } + +} diff --git a/modules/gcloud/src/test/java/org/testcontainers/containers/PubSubEmulatorContainerTest.java b/modules/gcloud/src/test/java/org/testcontainers/containers/PubSubEmulatorContainerTest.java new file mode 100644 index 00000000000..2a0acaa14e1 --- /dev/null +++ b/modules/gcloud/src/test/java/org/testcontainers/containers/PubSubEmulatorContainerTest.java @@ -0,0 +1,101 @@ +package org.testcontainers.containers; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.grpc.GrpcTransportChannel; +import com.google.api.gax.rpc.FixedTransportChannelProvider; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.cloud.pubsub.v1.Publisher; +import com.google.cloud.pubsub.v1.SubscriptionAdminClient; +import com.google.cloud.pubsub.v1.SubscriptionAdminSettings; +import com.google.cloud.pubsub.v1.TopicAdminClient; +import com.google.cloud.pubsub.v1.TopicAdminSettings; +import com.google.cloud.pubsub.v1.stub.GrpcSubscriberStub; +import com.google.cloud.pubsub.v1.stub.SubscriberStub; +import com.google.cloud.pubsub.v1.stub.SubscriberStubSettings; +import com.google.protobuf.ByteString; +import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.PubsubMessage; +import com.google.pubsub.v1.PullRequest; +import com.google.pubsub.v1.PullResponse; +import com.google.pubsub.v1.PushConfig; +import com.google.pubsub.v1.TopicName; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.io.IOException; +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.utility.DockerImageName; + +public class PubSubEmulatorContainerTest { + + public static final String PROJECT_ID = "my-project-id"; + + @Rule + public PubSubEmulatorContainer emulator = new PubSubEmulatorContainer(DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk:313.0.0")); + + @Test + public void testSimple() throws IOException { + String hostport = emulator.getEmulatorEndpoint(); + ManagedChannel channel = ManagedChannelBuilder.forTarget(hostport).usePlaintext().build(); + try { + TransportChannelProvider channelProvider = + FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel)); + NoCredentialsProvider credentialsProvider = NoCredentialsProvider.create(); + + String topicId = "my-topic-id"; + createTopic(topicId, channelProvider, credentialsProvider); + + String subscriptionId = "my-subscription-id"; + createSubscription(subscriptionId, topicId, channelProvider, credentialsProvider); + + Publisher publisher = Publisher.newBuilder(TopicName.of(PROJECT_ID, topicId)) + .setChannelProvider(channelProvider) + .setCredentialsProvider(credentialsProvider) + .build(); + PubsubMessage message = PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8("test message")).build(); + publisher.publish(message); + + SubscriberStubSettings subscriberStubSettings = + SubscriberStubSettings.newBuilder() + .setTransportChannelProvider(channelProvider) + .setCredentialsProvider(credentialsProvider) + .build(); + try (SubscriberStub subscriber = GrpcSubscriberStub.create(subscriberStubSettings)) { + PullRequest pullRequest = PullRequest.newBuilder() + .setMaxMessages(1) + .setSubscription(ProjectSubscriptionName.format(PROJECT_ID, subscriptionId)) + .build(); + PullResponse pullResponse = subscriber.pullCallable().call(pullRequest); + + assertThat(pullResponse.getReceivedMessagesList()).hasSize(1); + assertThat(pullResponse.getReceivedMessages(0).getMessage().getData().toStringUtf8()).isEqualTo("test message"); + } + } finally { + channel.shutdown(); + } + } + + private void createTopic(String topicId, TransportChannelProvider channelProvider, NoCredentialsProvider credentialsProvider) throws IOException { + TopicAdminSettings topicAdminSettings = TopicAdminSettings.newBuilder() + .setTransportChannelProvider(channelProvider) + .setCredentialsProvider(credentialsProvider) + .build(); + try (TopicAdminClient topicAdminClient = TopicAdminClient.create(topicAdminSettings)) { + TopicName topicName = TopicName.of(PROJECT_ID, topicId); + topicAdminClient.createTopic(topicName); + } + } + + private void createSubscription(String subscriptionId, String topicId, TransportChannelProvider channelProvider, NoCredentialsProvider credentialsProvider) throws IOException { + SubscriptionAdminSettings subscriptionAdminSettings = SubscriptionAdminSettings.newBuilder() + .setTransportChannelProvider(channelProvider) + .setCredentialsProvider(credentialsProvider) + .build(); + SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create(subscriptionAdminSettings); + ProjectSubscriptionName subscriptionName = ProjectSubscriptionName.of(PROJECT_ID, subscriptionId); + subscriptionAdminClient.createSubscription(subscriptionName, TopicName.of(PROJECT_ID, topicId), PushConfig.getDefaultInstance(), 10); + } + +} diff --git a/modules/gcloud/src/test/java/org/testcontainers/containers/SpannerEmulatorContainerTest.java b/modules/gcloud/src/test/java/org/testcontainers/containers/SpannerEmulatorContainerTest.java new file mode 100644 index 00000000000..5a47f9429ad --- /dev/null +++ b/modules/gcloud/src/test/java/org/testcontainers/containers/SpannerEmulatorContainerTest.java @@ -0,0 +1,79 @@ +package org.testcontainers.containers; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.cloud.NoCredentials; +import com.google.cloud.spanner.Database; +import com.google.cloud.spanner.DatabaseAdminClient; +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.Instance; +import com.google.cloud.spanner.InstanceAdminClient; +import com.google.cloud.spanner.InstanceConfigId; +import com.google.cloud.spanner.InstanceId; +import com.google.cloud.spanner.InstanceInfo; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.Statement; +import java.util.Arrays; +import java.util.concurrent.ExecutionException; +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.utility.DockerImageName; + +public class SpannerEmulatorContainerTest { + + @Rule + public SpannerEmulatorContainer emulator = new SpannerEmulatorContainer(DockerImageName.parse("gcr.io/cloud-spanner-emulator/emulator:1.1.0")); + + private static final String PROJECT_NAME = "test-project"; + private static final String INSTANCE_NAME = "test-instance"; + private static final String DATABASE_NAME = "test-database"; + + @Test + public void testSimple() throws ExecutionException, InterruptedException { + SpannerOptions options = SpannerOptions.newBuilder() + .setEmulatorHost(emulator.getEmulatorGrpcEndpoint()) + .setCredentials(NoCredentials.getInstance()) + .setProjectId(PROJECT_NAME) + .build(); + + Spanner spanner = options.getService(); + + InstanceId instanceId = createInstance(spanner); + + createDatabase(spanner); + + DatabaseId databaseId = DatabaseId.of(instanceId, DATABASE_NAME); + DatabaseClient dbClient = spanner.getDatabaseClient(databaseId); + dbClient.readWriteTransaction() + .run(tx -> { + String sql1 = "Delete from TestTable where 1=1"; + tx.executeUpdate(Statement.of(sql1)); + String sql = "INSERT INTO TestTable (Key, Value) VALUES (1, 'Java'), (2, 'Go')"; + tx.executeUpdate(Statement.of(sql)); + return null; + }); + + ResultSet resultSet = dbClient.readOnlyTransaction() + .executeQuery(Statement.of("select * from TestTable order by Key")); + resultSet.next(); + assertThat(resultSet.getLong(0)).isEqualTo(1); + assertThat(resultSet.getString(1)).isEqualTo("Java"); + } + + private void createDatabase(Spanner spanner) throws InterruptedException, ExecutionException { + DatabaseAdminClient dbAdminClient = spanner.getDatabaseAdminClient(); + Database database = dbAdminClient.createDatabase(INSTANCE_NAME, DATABASE_NAME, Arrays.asList("CREATE TABLE TestTable (Key INT64, Value STRING(MAX)) PRIMARY KEY (Key)")).get(); + } + + private InstanceId createInstance(Spanner spanner) throws InterruptedException, ExecutionException { + InstanceConfigId instanceConfig = InstanceConfigId.of(PROJECT_NAME, "emulator-config"); + InstanceId instanceId = InstanceId.of(PROJECT_NAME, INSTANCE_NAME); + InstanceAdminClient insAdminClient = spanner.getInstanceAdminClient(); + Instance instance = insAdminClient.createInstance(InstanceInfo.newBuilder(instanceId).setNodeCount(1).setDisplayName("Test instance").setInstanceConfigId(instanceConfig).build()).get(); + return instanceId; + } + +} diff --git a/modules/gcloud/src/test/resources/logback-test.xml b/modules/gcloud/src/test/resources/logback-test.xml new file mode 100644 index 00000000000..535e406fc13 --- /dev/null +++ b/modules/gcloud/src/test/resources/logback-test.xml @@ -0,0 +1,16 @@ + + + + + + %d{HH:mm:ss.SSS} %-5level %logger - %msg%n + + + + + + + + + diff --git a/modules/jdbc-test/build.gradle b/modules/jdbc-test/build.gradle index d8df69b094f..ec57ddcea41 100644 --- a/modules/jdbc-test/build.gradle +++ b/modules/jdbc-test/build.gradle @@ -15,7 +15,7 @@ dependencies { } compile 'commons-dbutils:commons-dbutils:1.7' - compile 'org.apache.tomcat:tomcat-jdbc:9.0.37' + compile 'org.apache.tomcat:tomcat-jdbc:9.0.39' compile 'org.vibur:vibur-dbcp:25.0' compile 'mysql:mysql-connector-java:8.0.21' } diff --git a/modules/jdbc/build.gradle b/modules/jdbc/build.gradle index 6453b49b052..2045461785e 100644 --- a/modules/jdbc/build.gradle +++ b/modules/jdbc/build.gradle @@ -7,7 +7,7 @@ dependencies { compileOnly 'org.jetbrains:annotations:20.1.0' testCompile 'commons-dbutils:commons-dbutils:1.7' testCompile 'org.vibur:vibur-dbcp:25.0' - testCompile 'org.apache.tomcat:tomcat-jdbc:9.0.37' + testCompile 'org.apache.tomcat:tomcat-jdbc:9.0.39' testCompile 'com.zaxxer:HikariCP-java6:2.3.13' testCompile 'com.googlecode.junit-toolbox:junit-toolbox:2.4' } diff --git a/modules/junit-jupiter/build.gradle b/modules/junit-jupiter/build.gradle index dbf54b8d291..28f6049faf4 100644 --- a/modules/junit-jupiter/build.gradle +++ b/modules/junit-jupiter/build.gradle @@ -8,14 +8,14 @@ dependencies { testCompile project(':postgresql') testCompile 'com.zaxxer:HikariCP:3.4.5' testCompile 'redis.clients:jedis:3.3.0' - testCompile 'org.apache.httpcomponents:httpclient:4.5.12' - testCompile ('org.mockito:mockito-core:3.5.11') { + testCompile 'org.apache.httpcomponents:httpclient:4.5.13' + testCompile ('org.mockito:mockito-core:3.5.13') { exclude(module: 'hamcrest-core') } testCompile 'org.assertj:assertj-core:3.17.2' testCompile 'org.junit.jupiter:junit-jupiter-params:5.7.0' - testRuntime 'org.postgresql:postgresql:42.2.16' + testRuntime 'org.postgresql:postgresql:42.2.17' testRuntime 'mysql:mysql-connector-java:8.0.21' testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.7.0' } diff --git a/modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java b/modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java index 08b9fb6f856..abe59ea88ca 100644 --- a/modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java +++ b/modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java @@ -6,8 +6,12 @@ import com.google.common.collect.ImmutableMap; import java.time.Duration; +import java.util.Collection; import java.util.UUID; import java.util.concurrent.TimeUnit; +import org.apache.kafka.clients.admin.AdminClient; +import org.apache.kafka.clients.admin.AdminClientConfig; +import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.consumer.ConsumerRecords; @@ -110,7 +114,15 @@ public void testConfluentPlatformVersion6() throws Exception { } protected void testKafkaFunctionality(String bootstrapServers) throws Exception { + testKafkaFunctionality(bootstrapServers, 1, 1); + } + + protected void testKafkaFunctionality(String bootstrapServers, int partitions, int rf) throws Exception { try ( + AdminClient adminClient = AdminClient.create(ImmutableMap.of( + AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers + )); + KafkaProducer producer = new KafkaProducer<>( ImmutableMap.of( ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers, @@ -131,6 +143,10 @@ protected void testKafkaFunctionality(String bootstrapServers) throws Exception ); ) { String topicName = "messages-" + UUID.randomUUID(); + + Collection topics = singletonList(new NewTopic(topicName, partitions, (short) rf)); + adminClient.createTopics(topics).all().get(30, TimeUnit.SECONDS); + consumer.subscribe(singletonList(topicName)); producer.send(new ProducerRecord<>(topicName, "testcontainers", "rulezzz")).get(); diff --git a/modules/localstack/build.gradle b/modules/localstack/build.gradle index f48b3cf71bb..29abca90878 100644 --- a/modules/localstack/build.gradle +++ b/modules/localstack/build.gradle @@ -3,9 +3,9 @@ description = "Testcontainers :: Localstack" dependencies { compile project(':testcontainers') - compileOnly 'com.amazonaws:aws-java-sdk-s3:1.11.870' - testCompile 'com.amazonaws:aws-java-sdk-s3:1.11.865' - testCompile 'com.amazonaws:aws-java-sdk-sqs:1.11.860' + compileOnly 'com.amazonaws:aws-java-sdk-s3:1.11.880' + testCompile 'com.amazonaws:aws-java-sdk-s3:1.11.880' + testCompile 'com.amazonaws:aws-java-sdk-sqs:1.11.880' testCompile 'com.amazonaws:aws-java-sdk-logs:1.11.807' - testCompile 'software.amazon.awssdk:s3:2.14.21' + testCompile 'software.amazon.awssdk:s3:2.15.7' } diff --git a/modules/mariadb/build.gradle b/modules/mariadb/build.gradle index 94164468855..e5f19eed97b 100644 --- a/modules/mariadb/build.gradle +++ b/modules/mariadb/build.gradle @@ -7,10 +7,10 @@ dependencies { compile project(':jdbc') compileOnly project(':r2dbc') - compileOnly 'org.mariadb:r2dbc-mariadb:0.8.3-beta1' + compileOnly 'org.mariadb:r2dbc-mariadb:0.8.4-rc' testCompile project(':jdbc-test') - testCompile 'org.mariadb.jdbc:mariadb-java-client:2.6.2' + testCompile 'org.mariadb.jdbc:mariadb-java-client:2.7.0' testCompile testFixtures(project(':r2dbc')) testCompile 'org.mariadb:r2dbc-mariadb:0.8.3-beta1' diff --git a/modules/mongodb/src/main/java/org/testcontainers/containers/MongoDBContainer.java b/modules/mongodb/src/main/java/org/testcontainers/containers/MongoDBContainer.java index 5fd2451480b..662c4b575f7 100644 --- a/modules/mongodb/src/main/java/org/testcontainers/containers/MongoDBContainer.java +++ b/modules/mongodb/src/main/java/org/testcontainers/containers/MongoDBContainer.java @@ -48,7 +48,22 @@ public MongoDBContainer(final DockerImageName dockerImageName) { ); } + /** + * Gets a replica set url for the default {@value #MONGODB_DATABASE_NAME_DEFAULT} database. + * + * @return a replica set url. + */ public String getReplicaSetUrl() { + return getReplicaSetUrl(MONGODB_DATABASE_NAME_DEFAULT); + } + + /** + * Gets a replica set url for a provided databaseName. + * + * @param databaseName a database name. + * @return a replica set url. + */ + public String getReplicaSetUrl(final String databaseName) { if (!isRunning()) { throw new IllegalStateException("MongoDBContainer should be started first"); } @@ -56,7 +71,7 @@ public String getReplicaSetUrl() { "mongodb://%s:%d/%s", getContainerIpAddress(), getMappedPort(MONGODB_INTERNAL_PORT), - MONGODB_DATABASE_NAME_DEFAULT + databaseName ); } diff --git a/modules/mongodb/src/test/java/org/testcontainers/containers/MongoDBContainerTest.java b/modules/mongodb/src/test/java/org/testcontainers/containers/MongoDBContainerTest.java index b18e7f15a01..ff5243acea7 100644 --- a/modules/mongodb/src/test/java/org/testcontainers/containers/MongoDBContainerTest.java +++ b/modules/mongodb/src/test/java/org/testcontainers/containers/MongoDBContainerTest.java @@ -13,8 +13,10 @@ import org.junit.Test; import org.testcontainers.utility.DockerImageName; +import static org.hamcrest.CoreMatchers.endsWith; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; public class MongoDBContainerTest { @@ -82,4 +84,15 @@ public void supportsMongoDB_4_4() { mongoDBContainer.start(); } } + + @Test + public void shouldTestDatabaseName() { + try ( + final MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10")) + ) { + mongoDBContainer.start(); + final String databaseName = "my-db"; + assertThat(mongoDBContainer.getReplicaSetUrl(databaseName), endsWith(databaseName)); + } + } } diff --git a/modules/postgresql/build.gradle b/modules/postgresql/build.gradle index ea6e4a87226..aa5db7028b5 100644 --- a/modules/postgresql/build.gradle +++ b/modules/postgresql/build.gradle @@ -11,7 +11,7 @@ dependencies { testCompile project(':jdbc-test') testCompile project(':test-support') - testCompile 'org.postgresql:postgresql:42.2.16' + testCompile 'org.postgresql:postgresql:42.2.17' testCompile testFixtures(project(':r2dbc')) testCompile 'io.r2dbc:r2dbc-postgresql:0.8.5.RELEASE' 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 cf5c762f2ad..db369824442 100644 --- a/modules/selenium/src/test/java/org/testcontainers/junit/BaseWebDriverContainerTest.java +++ b/modules/selenium/src/test/java/org/testcontainers/junit/BaseWebDriverContainerTest.java @@ -1,5 +1,10 @@ package org.testcontainers.junit; +import static java.lang.String.format; +import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; +import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; + +import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.NotNull; import org.junit.ClassRule; import org.openqa.selenium.By; @@ -11,12 +16,6 @@ import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; import org.testcontainers.utility.DockerImageName; -import java.util.concurrent.TimeUnit; - -import static java.lang.String.format; -import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals; -import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; - /** * */ @@ -26,7 +25,7 @@ public class BaseWebDriverContainerTest { public static Network NETWORK = Network.newNetwork(); @ClassRule - public static GenericContainer HELLO_WORLD = new GenericContainer<>(DockerImageName.parse("testcontainers/helloworld:1.0.0")) + public static GenericContainer HELLO_WORLD = new GenericContainer<>(DockerImageName.parse("testcontainers/helloworld:1.1.0")) .withNetwork(NETWORK) .withNetworkAliases("helloworld") .withExposedPorts(8080, 8081) diff --git a/modules/spock/build.gradle b/modules/spock/build.gradle index 3d0948e9e83..86724262a29 100644 --- a/modules/spock/build.gradle +++ b/modules/spock/build.gradle @@ -13,9 +13,9 @@ dependencies { testCompile project(':postgresql') testCompile 'com.zaxxer:HikariCP:3.4.5' - testCompile 'org.apache.httpcomponents:httpclient:4.5.12' + testCompile 'org.apache.httpcomponents:httpclient:4.5.13' - testRuntime 'org.postgresql:postgresql:42.2.16' + testRuntime 'org.postgresql:postgresql:42.2.17' testRuntime 'mysql:mysql-connector-java:8.0.21' testCompileClasspath 'org.jetbrains:annotations:20.1.0' diff --git a/settings.gradle b/settings.gradle index 2ea21599ceb..849a1ade06b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -46,6 +46,7 @@ buildCache { region = 'fra1' bucket = 'testcontainers' path = 'cache' + reducedRedundancy = false push = isMasterBuild && !System.getenv("READ_ONLY_REMOTE_GRADLE_CACHE") headers = [ 'x-amz-acl': 'public-read'