Skip to content

Commit 693ea8c

Browse files
authored
Add DatastoreEmulatorContainer to gcloud module (#782)
1 parent 96250a8 commit 693ea8c

File tree

6 files changed

+147
-8
lines changed

6 files changed

+147
-8
lines changed

docs/modules/gcloud.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ Testcontainers module for the Google Cloud Platform's [Cloud SDK](https://cloud.
88
npm install @testcontainers/gcloud --save-dev
99
```
1010

11+
Currently, the module supports `Firestore` emulators in Native mode and Datastore mode. In order to use them, you should use the following classes:
1112

12-
Currently, the module supports `Firestore` emulators. In order to use it, you should use the following classes:
13-
14-
Class | Container Image
15-
-|-
16-
FirestoreEmulatorContainer | [gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators](https://gcr.io/google.com/cloudsdktool/google-cloud-cli)
13+
Mode | Class | Container Image
14+
-|-|-
15+
Native mode | FirestoreEmulatorContainer | [gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators](https://gcr.io/google.com/cloudsdktool/google-cloud-cli)
16+
Datastore mode | DatastoreEmulatorContainer | [gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators](https://gcr.io/google.com/cloudsdktool/google-cloud-cli)
1717

1818
## Examples
1919

20-
### Firestore
20+
### Firestore Native mode
2121

2222
<!--codeinclude-->
2323
[Starting a Firestore Emulator container with the default image](../../packages/modules/gcloud/src/firestore-emulator-container.test.ts) inside_block:firestore4
@@ -26,3 +26,13 @@ FirestoreEmulatorContainer | [gcr.io/google.com/cloudsdktool/google-cloud-cli:em
2626
<!--codeinclude-->
2727
[Starting a Firestore Emulator container with a custom emulator image](../../packages/modules/gcloud/src/firestore-emulator-container.test.ts) inside_block:firestore5
2828
<!--/codeinclude-->
29+
30+
### Firestore Datastore mode
31+
32+
<!--codeinclude-->
33+
[Starting a Datastore Emulator container with the default image](../../packages/modules/gcloud/src/datastore-emulator-container.test.ts) inside_block:datastore4
34+
<!--/codeinclude-->
35+
36+
<!--codeinclude-->
37+
[Starting a Datastore Emulator container with a custom emulator image](../../packages/modules/gcloud/src/datastore-emulator-container.test.ts) inside_block:datastore5
38+
<!--/codeinclude-->

package-lock.json

Lines changed: 51 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/modules/gcloud/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"testcontainers": "^10.10.4"
3535
},
3636
"devDependencies": {
37+
"@google-cloud/datastore": "^9.0.0",
3738
"@google-cloud/firestore": "7.9.0",
3839
"firebase-admin": "12.2.0"
3940
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { DatastoreEmulatorContainer, StartedDatastoreEmulatorContainer } from "./datastore-emulator-container";
2+
import { Datastore } from "@google-cloud/datastore";
3+
4+
describe("DatastoreEmulatorContainer", () => {
5+
jest.setTimeout(240_000);
6+
7+
// datastore4 {
8+
it("should work using default version", async () => {
9+
const datastoreEmulatorContainer = await new DatastoreEmulatorContainer().start();
10+
11+
await checkDatastore(datastoreEmulatorContainer);
12+
13+
await datastoreEmulatorContainer.stop();
14+
});
15+
// }
16+
17+
// datastore5 {
18+
it("should work using version 468.0.0", async () => {
19+
const datastoreEmulatorContainer = await new DatastoreEmulatorContainer(
20+
"gcr.io/google.com/cloudsdktool/google-cloud-cli:468.0.0-emulators"
21+
).start();
22+
23+
await checkDatastore(datastoreEmulatorContainer);
24+
25+
await datastoreEmulatorContainer.stop();
26+
});
27+
28+
// }
29+
30+
async function checkDatastore(datastoreEmulatorContainer: StartedDatastoreEmulatorContainer) {
31+
expect(datastoreEmulatorContainer).toBeDefined();
32+
const testProjectId = "test-project";
33+
const testKind = "test-kind";
34+
const testId = "123";
35+
const databaseConfig = { projectId: testProjectId, apiEndpoint: datastoreEmulatorContainer.getEmulatorEndpoint() };
36+
const datastore = new Datastore(databaseConfig);
37+
38+
const key = datastore.key([testKind, testId]);
39+
const data = { message: "Hello, Datastore!" };
40+
await datastore.save({ key, data });
41+
const [entity] = await datastore.get(key);
42+
43+
expect(entity).toEqual({ message: "Hello, Datastore!", [Datastore.KEY]: key });
44+
}
45+
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { AbstractStartedContainer, GenericContainer, StartedTestContainer, Wait } from "testcontainers";
2+
3+
const EMULATOR_PORT = 8080;
4+
const CMD = `gcloud beta emulators firestore start --host-port 0.0.0.0:${EMULATOR_PORT} --database-mode=datastore-mode`;
5+
const DEFAULT_IMAGE = "gcr.io/google.com/cloudsdktool/cloud-sdk";
6+
7+
export class DatastoreEmulatorContainer extends GenericContainer {
8+
constructor(image = DEFAULT_IMAGE) {
9+
super(image);
10+
this.withExposedPorts(EMULATOR_PORT)
11+
.withCommand(["/bin/sh", "-c", CMD])
12+
.withWaitStrategy(Wait.forLogMessage(RegExp(".*running.*"), 1))
13+
.withStartupTimeout(120_000);
14+
}
15+
16+
public override async start(): Promise<StartedDatastoreEmulatorContainer> {
17+
return new StartedDatastoreEmulatorContainer(await super.start());
18+
}
19+
}
20+
21+
export class StartedDatastoreEmulatorContainer extends AbstractStartedContainer {
22+
constructor(startedTestContainer: StartedTestContainer) {
23+
super(startedTestContainer);
24+
}
25+
26+
/**
27+
* @return a <code>host:port</code> pair corresponding to the address on which the emulator is
28+
* reachable from the test host machine.
29+
*/
30+
public getEmulatorEndpoint(): string {
31+
return `${this.getHost()}:${this.getMappedPort(EMULATOR_PORT)}`;
32+
}
33+
}

packages/modules/gcloud/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { FirestoreEmulatorContainer, StartedFirestoreEmulatorContainer } from "./firestore-emulator-container";
2+
export { DatastoreEmulatorContainer, StartedDatastoreEmulatorContainer } from "./datastore-emulator-container";

0 commit comments

Comments
 (0)