Skip to content
Open
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
8 changes: 7 additions & 1 deletion src/apphosting/secrets/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
gcsm.labels.restore();
gcsm.getIamPolicy.throws("Unexpected getIamPolicy call");
gcsm.setIamPolicy.throws("Unexpected setIamPolicy call");
// Unstubbed, this reaches the Compute API over the network and races mocha's 2s
// timeout. The fake derives the address from its argument so the tests still pin
// that the project number is passed through.
sinon
.stub(gce, "getDefaultServiceAccount")
.callsFake((pn: string) => Promise.resolve(`${pn}-compute@developer.gserviceaccount.com`));
});

afterEach(() => {
Expand All @@ -38,7 +44,7 @@
it("uses explicit account", async () => {
const backend = {
serviceAccount: "sa",
} as any as apphosting.Backend;

Check warning on line 47 in src/apphosting/secrets/index.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unexpected any. Specify a different type
expect(await secrets.serviceAccountsForBackend("number", backend)).to.deep.equal({
buildServiceAccount: "sa",
runServiceAccount: "sa",
Expand All @@ -46,10 +52,10 @@
});

it("has a fallback for legacy SAs", async () => {
const backend = {} as any as apphosting.Backend;

Check warning on line 55 in src/apphosting/secrets/index.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unexpected any. Specify a different type
expect(await secrets.serviceAccountsForBackend("number", backend)).to.deep.equal({
buildServiceAccount: gcb.getDefaultServiceAccount("number"),
runServiceAccount: await gce.getDefaultServiceAccount("number"),
runServiceAccount: "number-compute@developer.gserviceaccount.com",
});
});
});
Expand Down Expand Up @@ -202,15 +208,15 @@
let err;
try {
await secrets.upsertSecret("project", "secret");
} catch (e: any) {

Check warning on line 211 in src/apphosting/secrets/index.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unexpected any. Specify a different type
err = e;

Check warning on line 212 in src/apphosting/secrets/index.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe assignment of an `any` value
}

expect(err.message).to.equal(

Check warning on line 215 in src/apphosting/secrets/index.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .message on an `any` value
"Unexpected error loading secret: HTTP Error: 403, This API method requires billing to be enabled.",
);
expect(err.status).to.equal(403);

Check warning on line 218 in src/apphosting/secrets/index.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .status on an `any` value
expect(err.original).to.equal(original);

Check warning on line 219 in src/apphosting/secrets/index.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .original on an `any` value
expect(gcsm.createSecret).to.not.have.been.called;
});
});
Expand Down Expand Up @@ -603,8 +609,8 @@
it("creates a new secret and grants access", async () => {
gcsm.getSecret.rejects({ status: 404 });
utils.readSecretValue.resolves("secretValue");
gcsm.addVersion.resolves({

Check warning on line 612 in src/apphosting/secrets/index.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe argument of type `any` assigned to a parameter of type `Required<SecretVersion> | undefined`
secret: { name: "secret", projectId: "project" } as any,

Check warning on line 613 in src/apphosting/secrets/index.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unexpected any. Specify a different type

Check warning on line 613 in src/apphosting/secrets/index.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe assignment of an `any` value
versionId: "1",
} as any);
prompt.select.resolves("production");
Expand Down
8 changes: 8 additions & 0 deletions src/deploy/functions/checkIam.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as sinon from "sinon";
import * as checkIam from "./checkIam";
import * as storage from "../../gcp/storage";
import * as rm from "../../gcp/resourceManager";
import * as gce from "../../gcp/computeEngine";
import * as backend from "./backend";

const projectId = "my-project";
Expand Down Expand Up @@ -30,6 +31,13 @@ describe("checkIam", () => {
let setIamStub: sinon.SinonStub;

beforeEach(() => {
// Unstubbed, this reaches the Compute API over the network and each test that
// needs the default service account races mocha's 2s timeout. The fake derives
// the address from its argument so the tests still pin that checkIam passes the
// project number through.
sinon
.stub(gce, "getDefaultServiceAccount")
.callsFake((pn: string) => Promise.resolve(`${pn}-compute@developer.gserviceaccount.com`));
storageStub = sinon
.stub(storage, "getServiceAccount")
.throws("unexpected call to storage.getServiceAccount");
Expand Down
13 changes: 12 additions & 1 deletion src/deploy/functions/release/fabricator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import * as gce from "../../../gcp/computeEngine";
import * as iam from "../../../gcp/iam";
import * as resourcemanager from "../../../gcp/resourceManager";

const DEFAULT_COMPUTE_SERVICE_ACCOUNT = "1234567-compute@developer.gserviceaccount.com";

describe("Fabricator", () => {
// Stub all GCP APIs to make sure this test is hermetic
let gcf: sinon.SinonStubbedInstance<typeof gcfNS>;
Expand All @@ -40,6 +42,7 @@ describe("Fabricator", () => {
let tasks: sinon.SinonStubbedInstance<typeof cloudtasksNS>;
let services: sinon.SinonStubbedInstance<typeof servicesNS>;
let identityPlatform: sinon.SinonStubbedInstance<typeof identityPlatformNS>;
let computeEngine: sinon.SinonStubbedInstance<typeof gce>;

beforeEach(() => {
gcf = sinon.stub(gcfNS);
Expand All @@ -53,6 +56,7 @@ describe("Fabricator", () => {
tasks = sinon.stub(cloudtasksNS);
services = sinon.stub(servicesNS);
identityPlatform = sinon.stub(identityPlatformNS);
computeEngine = sinon.stub(gce);

gcf.functionFromEndpoint.restore();
gcfv2.functionFromEndpoint.restore();
Expand Down Expand Up @@ -104,6 +108,13 @@ describe("Fabricator", () => {
identityPlatform.setBlockingFunctionsConfig.rejects(
new Error("unexpected identityPlatform.setBlockingFunctionsConfig"),
);
// Unstubbed, this reaches the Compute API over the network and every test that
// needs the default service account races mocha's 2s timeout. The fake derives
// the address from its argument so the tests still pin that the fabricator passes
// the project number through.
computeEngine.getDefaultServiceAccount.callsFake((pn: string) =>
Promise.resolve(`${pn}-compute@developer.gserviceaccount.com`),
);
});

afterEach(() => {
Expand Down Expand Up @@ -892,7 +903,7 @@ describe("Fabricator", () => {

await fab.createV2Function(ep, new scraper.SourceTokenScraper());
expect(run.setInvokerCreate).to.have.been.calledWith(ep.project, "service", [
await gce.getDefaultServiceAccount(fab.projectNumber),
DEFAULT_COMPUTE_SERVICE_ACCOUNT,
]);
});

Expand Down
15 changes: 15 additions & 0 deletions src/gcp/cloudscheduler.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { expect } from "chai";
import * as sinon from "sinon";
import nock from "../test/helpers/nock";

import { FirebaseError } from "../error";
import * as api from "../api";
import * as backend from "../deploy/functions/backend";
import * as cloudscheduler from "./cloudscheduler";
import * as gce from "./computeEngine";
import { cloneDeep } from "../utils";

const VERSION = "v1";
Expand Down Expand Up @@ -157,6 +159,19 @@ describe("cloudscheduler", () => {
});

describe("jobFromEndpoint", () => {
beforeEach(() => {
// Unstubbed, this reaches the Compute API over the network and each v2 endpoint
// test races mocha's 2s timeout. The fake derives the address from its argument
// so the tests still pin that jobFromEndpoint passes the project number through.
sinon
.stub(gce, "getDefaultServiceAccount")
.callsFake((pn: string) => Promise.resolve(`${pn}-compute@developer.gserviceaccount.com`));
});

afterEach(() => {
sinon.verifyAndRestore();
});

const V1_ENDPOINT: backend.Endpoint = {
platform: "gcfv1",
id: "id",
Expand Down
Loading