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 for more information on our incubating modules policy.
Testcontainers module for the Google Cloud Platform's Cloud 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:
Class | Container Image |
---|---|
BigQueryEmulatorContainer | ghcr.io/goccy/bigquery-emulator |
BigtableEmulatorContainer | gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators |
DatastoreEmulatorContainer | gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators |
FirestoreEmulatorContainer | gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators |
SpannerEmulatorContainer | gcr.io/cloud-spanner-emulator/emulator |
PubSubEmulatorContainer | gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators |
Usage example
BigQuery
Start BigQuery Emulator during a test:
BigQueryEmulatorContainer container = new BigQueryEmulatorContainer("ghcr.io/goccy/bigquery-emulator:0.4.3")
String url = container.getEmulatorHttpEndpoint();
BigQueryOptions options = BigQueryOptions
.newBuilder()
.setProjectId(container.getProjectId())
.setHost(url)
.setLocation(url)
.setCredentials(NoCredentials.getInstance())
.build();
BigQuery bigQuery = options.getService();
Bigtable
Start Bigtable Emulator during a test:
public BigtableEmulatorContainer emulator = new BigtableEmulatorContainer(
DockerImageName.parse("gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0-emulators")
);
Create a test Bigtable table in the Emulator:
private void createTable(
TransportChannelProvider channelProvider,
CredentialsProvider credentialsProvider,
String tableName
) throws IOException {
EnhancedBigtableTableAdminStub stub = EnhancedBigtableTableAdminStub.createEnhanced(
BigtableTableAdminStubSettings
.newBuilder()
.setTransportChannelProvider(channelProvider)
.setCredentialsProvider(credentialsProvider)
.build()
);
try (BigtableTableAdminClient client = BigtableTableAdminClient.create(PROJECT_ID, INSTANCE_ID, stub)) {
Table table = client.createTable(CreateTableRequest.of(tableName).addFamily("name"));
}
}
Test against the Emulator:
public void testSimple() throws IOException, InterruptedException, ExecutionException {
ManagedChannel channel = ManagedChannelBuilder.forTarget(emulator.getEmulatorEndpoint()).usePlaintext().build();
TransportChannelProvider channelProvider = FixedTransportChannelProvider.create(
GrpcTransportChannel.create(channel)
);
NoCredentialsProvider credentialsProvider = NoCredentialsProvider.create();
try {
createTable(channelProvider, credentialsProvider, "test-table");
BigtableDataClient client = BigtableDataClient.create(
BigtableDataSettings
.newBuilderForEmulator(emulator.getHost(), emulator.getEmulatorPort())
.setProjectId(PROJECT_ID)
.setInstanceId(INSTANCE_ID)
.build()
);
client.mutateRow(RowMutation.create("test-table", "1").setCell("name", "firstName", "Ray"));
Row row = client.readRow("test-table", "1");
List<RowCell> cells = row.getCells("name", "firstName");
assertThat(cells).isNotNull().hasSize(1);
assertThat(cells.get(0).getValue().toStringUtf8()).isEqualTo("Ray");
} finally {
channel.shutdown();
}
}
Datastore
Start Datastore Emulator during a test:
public DatastoreEmulatorContainer emulator = new DatastoreEmulatorContainer(
DockerImageName.parse("gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0-emulators")
);
And test against the Emulator:
@Test
public void testSimple() {
DatastoreOptions options = DatastoreOptions
.newBuilder()
.setHost(emulator.getEmulatorEndpoint())
.setCredentials(NoCredentials.getInstance())
.setRetrySettings(ServiceOptions.getNoRetrySettings())
.setProjectId(emulator.getProjectId())
.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");
}
See more examples:
Firestore
Start Firestore Emulator during a test:
public FirestoreEmulatorContainer emulator = new FirestoreEmulatorContainer(
DockerImageName.parse("gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0-emulators")
);
And test against the Emulator:
@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<String, Object> data = new HashMap<>();
data.put("first", "Ada");
data.put("last", "Lovelace");
ApiFuture<WriteResult> result = docRef.set(data);
result.get();
ApiFuture<QuerySnapshot> query = users.get();
QuerySnapshot querySnapshot = query.get();
assertThat(querySnapshot.getDocuments().get(0).getData()).containsEntry("first", "Ada");
}
See more examples:
Spanner
Start Spanner Emulator during a test:
public SpannerEmulatorContainer emulator = new SpannerEmulatorContainer(
DockerImageName.parse("gcr.io/cloud-spanner-emulator/emulator:1.4.0")
);
Create a test Spanner Instance in the Emulator:
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;
}
Create a test Database in the Emulator:
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();
}
And test against the Emulator:
@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");
}
See more examples:
Pub/Sub
Start Pub/Sub Emulator during a test:
public PubSubEmulatorContainer emulator = new PubSubEmulatorContainer(
DockerImageName.parse("gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0-emulators")
);
Create a test Pub/Sub topic in the Emulator:
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);
}
}
Create a test Pub/Sub subscription in the Emulator:
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);
SubscriptionName subscriptionName = SubscriptionName.of(PROJECT_ID, subscriptionId);
subscriptionAdminClient.createSubscription(
subscriptionName,
TopicName.of(PROJECT_ID, topicId),
PushConfig.getDefaultInstance(),
10
);
}
And test against the Emulator:
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();
}
}
See more examples:
Adding this module to your project dependencies
Add the following dependency to your pom.xml
/build.gradle
file:
testImplementation "org.testcontainers:gcloud:1.20.3"
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>gcloud</artifactId>
<version>1.20.3</version>
<scope>test</scope>
</dependency>