Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add autoUpdateExternalUrl to CloudStorageEmulatorContainer #825

Merged
merged 2 commits into from
Aug 31, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions packages/modules/gcloud/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"firestore",
"pubsub",
"cloudstorage",
"gcs",
"testing",
"docker",
"testcontainers"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe("CloudStorageEmulatorContainer", () => {
await cloudstorageEmulatorContainer.stop();
});

it("should update the external URL", async () => {
it("should use the provided external URL", async () => {
const cloudstorageEmulatorContainer = await new CloudStorageEmulatorContainer()
.withExternalURL("http://cdn.company.local")
.start();
Expand Down Expand Up @@ -104,6 +104,38 @@ describe("CloudStorageEmulatorContainer", () => {
await cloudstorageEmulatorContainer.stop();
});

it("should use emulator endpoint as default external URL", async () => {
let configUpdated = false;

server.events.on("request:start", ({ request }) => {
if (request.url.includes("/_internal/config")) configUpdated = true;
});

const container = await new CloudStorageEmulatorContainer().start();

expect(configUpdated).toBe(true);
expect(container.getExternalUrl()).toBe(container.getEmulatorEndpoint());
expect((await fetch(`${container.getExternalUrl()}/_internal/healthcheck`)).status).toBe(200);

await container.stop();
});

it("should allow skipping updating the external URL automatically", async () => {
let configUpdated = false;

server.events.on("request:start", ({ request }) => {
if (request.url.includes("/_internal/config")) configUpdated = true;
});

const container = await new CloudStorageEmulatorContainer().withAutoUpdateExternalUrl(false).start();

expect(configUpdated).toBe(false);
expect(container.getExternalUrl()).toBe(undefined);
expect((await fetch(`${container.getEmulatorEndpoint()}/_internal/healthcheck`)).status).toBe(200);

await container.stop();
});

async function checkCloudStorage(cloudstorageEmulatorContainer: StartedCloudStorageEmulatorContainer) {
expect(cloudstorageEmulatorContainer).toBeDefined();

Expand Down
27 changes: 17 additions & 10 deletions packages/modules/gcloud/src/cloudstorage-emulator-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ const DEFAULT_IMAGE = "fsouza/fake-gcs-server";
export class CloudStorageEmulatorContainer extends GenericContainer {
private _externalURL?: string;
private _publicHost?: string;
private autoUpdateExternalUrl = true;

constructor(image = DEFAULT_IMAGE) {
super(image);

this.withExposedPorts(PORT)
.withWaitStrategy(Wait.forLogMessage(/server started/g, 1))
.withStartupTimeout(120_000);
this.withExposedPorts(PORT).withWaitStrategy(Wait.forLogMessage("server started")).withStartupTimeout(120_000);
}

public withExternalURL(url: string): CloudStorageEmulatorContainer {
Expand All @@ -26,6 +25,11 @@ export class CloudStorageEmulatorContainer extends GenericContainer {
return this;
}

public withAutoUpdateExternalUrl(autoUpdateExternalUrl: boolean): this {
this.autoUpdateExternalUrl = autoUpdateExternalUrl;
return this;
}

public override async start(): Promise<StartedCloudStorageEmulatorContainer> {
// Determine the valid entrypoint command when starting the Cloud Storage server

Expand All @@ -42,7 +46,14 @@ export class CloudStorageEmulatorContainer extends GenericContainer {
];
this.withEntrypoint(entrypoint);

return new StartedCloudStorageEmulatorContainer(await super.start(), this._externalURL);
const container = new StartedCloudStorageEmulatorContainer(await super.start(), this._externalURL);

if (this.autoUpdateExternalUrl && this._externalURL === undefined) {
// Done after starting because we don't know the port ahead of time
await container.updateExternalUrl(container.getEmulatorEndpoint());
}

return container;
}
}

Expand Down Expand Up @@ -100,11 +111,7 @@ export class StartedCloudStorageEmulatorContainer extends AbstractStartedContain
* @return a <code>host:port</code> pair corresponding to the address on which the emulator is
* reachable from the test host machine.
*/
public getExternalUrl(): string {
if (this._externalURL) {
return this._externalURL;
} else {
return this.getEmulatorEndpoint();
}
Comment on lines -103 to -108
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this fallback because undefined is a valid state (i.e., "not set"), and _externalURL will usually be up-to-date, thanks to updateExternalUrl.

public getExternalUrl(): string | undefined {
return this._externalURL;
}
}
Loading