Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion docs/modules/gcloud.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Testcontainers module for the Google Cloud Platform's [Cloud SDK](https://cloud.google.com/sdk/).

Currently, the module supports `BigQuery`, `Bigtable`, `Datastore`, `Firestore`, `Spanner`, and `Pub/Sub` emulators. In order to use it, you should use the following classes:
Currently, the module supports `BigQuery`, `Bigtable`, `Datastore`, `Firestore`, `Spanner`, `Pub/Sub`, and `CloudStorage` emulators. In order to use it, you should use the following classes:

Class | Container Image
-|-
Expand All @@ -15,6 +15,7 @@ DatastoreEmulatorContainer | [gcr.io/google.com/cloudsdktool/google-cloud-cli:em
FirestoreEmulatorContainer | [gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators](https://gcr.io/google.com/cloudsdktool/google-cloud-cli)
SpannerEmulatorContainer | [gcr.io/cloud-spanner-emulator/emulator](https://gcr.io/cloud-spanner-emulator/emulator)
PubSubEmulatorContainer | [gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators](https://gcr.io/google.com/cloudsdktool/google-cloud-cli)
CloudStorageEmulatorContainer | [hub.docker.com/r/fsouza/fake-gcs-server](https://hub.docker.com/r/fsouza/fake-gcs-server)

## Usage example

Expand Down Expand Up @@ -150,6 +151,15 @@ See more examples:
* [Full sample code](https://github.com/testcontainers/testcontainers-java/tree/main/modules/gcloud/src/test/java/org/testcontainers/containers/PubSubEmulatorContainerTest.java)
* [With Spring Boot](https://github.com/saturnism/testcontainers-gcloud-examples/tree/main/springboot/pubsub-example/src/test/java/com/example/springboot/pubsub/PubSubIntegrationTests.java)

### CloudStorage

Start the CloudStorage emulator and test against it:

<!--codeinclude-->
[Testing with a CloudStorage Emulator container](../../modules/gcloud/src/test/java/org/testcontainers/containers/CloudStorageEmulatorContainerTest.java) inside_block:testWithCloudStorageEmulatorContainer
<!--/codeinclude-->


## Adding this module to your project dependencies

Add the following dependency to your `pom.xml`/`build.gradle` file:
Expand Down
1 change: 1 addition & 0 deletions modules/gcloud/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ dependencies {
testImplementation 'com.google.cloud:google-cloud-pubsub'
testImplementation 'com.google.cloud:google-cloud-spanner'
testImplementation 'com.google.cloud:google-cloud-bigtable'
testImplementation 'com.google.cloud:google-cloud-storage'
testImplementation 'org.assertj:assertj-core:3.26.3'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package org.testcontainers.containers;

import org.testcontainers.containers.wait.strategy.WaitStrategy;
import org.testcontainers.containers.wait.strategy.WaitStrategyTarget;
import org.testcontainers.utility.DockerImageName;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

/**
* Testcontainers implementation for Google Cloud Storage.
* Default port: 4443
* <p>
* Supported image: {@code hub.docker.com/r/fsouza/fake-gcs-server}
* <p>
* @see <a href="https://github.com/fsouza/fake-gcs-server">fsouza/fake-gcs-server on GitHub</a>
*/
public class CloudStorageEmulatorContainer extends GenericContainer<CloudStorageEmulatorContainer> {

public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("fsouza/fake-gcs-server");

public static final int EMULATOR_PORT = 4443;

public CloudStorageEmulatorContainer(String image) {
this(DockerImageName.parse(image));
}

public CloudStorageEmulatorContainer(DockerImageName dockerImageName) {
super(dockerImageName);
dockerImageName.assertCompatibleWith(DEFAULT_IMAGE);
addExposedPorts(EMULATOR_PORT);
withCreateContainerCmdModifier(cmd -> cmd.withEntrypoint("/bin/fake-gcs-server", "-scheme", "http"));
waitingFor(
new WaitStrategy() {
@Override
public void waitUntilReady(WaitStrategyTarget target) {
updateFakeGcsExternalUrl(getEmulatorHttpEndpoint());
}

@Override
public WaitStrategy withStartupTimeout(Duration startupTimeout) {
return getWaitStrategy().withStartupTimeout(startupTimeout);
}
}
);
}

public String getEmulatorHttpEndpoint() {
return String.format("http://%s:%d", getHost(), getMappedPort(EMULATOR_PORT));
}

private static void updateFakeGcsExternalUrl(String gcsUrl) {
String json = String.format("{ \"externalUrl\": \"%s\" }", gcsUrl);

HttpRequest req = HttpRequest
.newBuilder()
.uri(URI.create(gcsUrl + "/_internal/config"))
.header("Content-Type", "application/json")
.PUT(HttpRequest.BodyPublishers.ofString(json))
.build();

try {
HttpResponse<Void> response = HttpClient
.newBuilder()
.build()
.send(req, HttpResponse.BodyHandlers.discarding());

if (response.statusCode() != 200) {
throw new RuntimeException(
"error updating fake-gcs-server with external url, response status code " +
response.statusCode() +
" != 200"
);
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.testcontainers.containers;

import com.google.cloud.NoCredentials;
import com.google.cloud.storage.Blob;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.BucketInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class CloudStorageEmulatorContainerTest {

// testWithCloudStorageEmulatorContainer {
@Test
public void shouldWriteAndReadFile() {
final String BUCKET_NAME = "test-bucket";
final String FILE_NAME = "test-file.txt";
final String FILE_CONTENT = "test file content";

try (
CloudStorageEmulatorContainer container = new CloudStorageEmulatorContainer("fsouza/fake-gcs-server:1.50.2")
) {
container.start();

Storage storageClient = StorageOptions
.newBuilder()
.setHost(container.getEmulatorHttpEndpoint())
.setProjectId("test-project")
.setCredentials(NoCredentials.getInstance())
.build()
.getService();
storageClient.create(BucketInfo.of(BUCKET_NAME));

storageClient.create(BlobInfo.newBuilder(BUCKET_NAME, FILE_NAME).build(), FILE_CONTENT.getBytes());

Blob blob = storageClient.get(BUCKET_NAME, FILE_NAME);
assertThat(blob.getContent()).asString().isEqualTo(FILE_CONTENT);
}
}
// }

}