Use new feature flag architecture when uploading databases

This commit is contained in:
Henry Mercer
2021-12-14 20:48:32 +00:00
parent 04671efa1d
commit d6499fad61
18 changed files with 158 additions and 177 deletions

View File

@@ -10,6 +10,7 @@ import * as apiClient from "./api-client";
import { setCodeQL } from "./codeql";
import { Config } from "./config-utils";
import { uploadDatabases } from "./database-upload";
import { createFeatureFlags, FeatureFlags } from "./feature-flags";
import { Language } from "./languages";
import { RepositoryNwo } from "./repository";
import {
@@ -32,6 +33,11 @@ test.beforeEach(() => {
initializeEnvironment(Mode.actions, "1.2.3");
});
const uploadToUploadsDomainFlags = createFeatureFlags([
"database_uploads_enabled",
"uploads_domain_enabled",
]);
const testRepoName: RepositoryNwo = { owner: "github", repo: "example" };
const testApiDetails: GitHubApiDetails = {
auth: "1234",
@@ -55,44 +61,25 @@ function getTestConfig(tmpDir: string): Config {
};
}
function mockHttpRequests(
optInStatusCode: number,
useUploadDomain?: boolean,
databaseUploadStatusCode?: number
async function mockHttpRequests(
featureFlags: FeatureFlags,
databaseUploadStatusCode: number
) {
// Passing an auth token is required, so we just use a dummy value
const client = github.getOctokit("123");
const requestSpy = sinon.stub(client, "request");
const optInSpy = requestSpy.withArgs(
"GET /repos/:owner/:repo/code-scanning/codeql/databases"
);
if (optInStatusCode < 300) {
optInSpy.resolves({
status: optInStatusCode,
data: {
useUploadDomain,
},
headers: {},
url: "GET /repos/:owner/:repo/code-scanning/codeql/databases",
});
const url = (await featureFlags.getUploadsDomainEnabled())
? "POST https://uploads.github.com/repos/:owner/:repo/code-scanning/codeql/databases/:language?name=:name"
: "PUT /repos/:owner/:repo/code-scanning/codeql/databases/:language";
const databaseUploadSpy = requestSpy.withArgs(url);
if (databaseUploadStatusCode < 300) {
databaseUploadSpy.resolves(undefined);
} else {
optInSpy.throws(new HTTPError("some error message", optInStatusCode));
}
if (databaseUploadStatusCode !== undefined) {
const url = useUploadDomain
? "POST https://uploads.github.com/repos/:owner/:repo/code-scanning/codeql/databases/:language?name=:name"
: "PUT /repos/:owner/:repo/code-scanning/codeql/databases/:language";
const databaseUploadSpy = requestSpy.withArgs(url);
if (databaseUploadStatusCode < 300) {
databaseUploadSpy.resolves(undefined);
} else {
databaseUploadSpy.throws(
new HTTPError("some error message", databaseUploadStatusCode)
);
}
databaseUploadSpy.throws(
new HTTPError("some error message", databaseUploadStatusCode)
);
}
sinon.stub(apiClient, "getApiClient").value(() => client);
@@ -111,6 +98,7 @@ test("Abort database upload if 'upload-database' input set to false", async (t)
await uploadDatabases(
testRepoName,
getTestConfig(tmpDir),
uploadToUploadsDomainFlags,
testApiDetails,
getRecordingLogger(loggedMessages)
);
@@ -140,6 +128,7 @@ test("Abort database upload if running against GHES", async (t) => {
await uploadDatabases(
testRepoName,
config,
createFeatureFlags([]),
testApiDetails,
getRecordingLogger(loggedMessages)
);
@@ -169,6 +158,7 @@ test("Abort database upload if running against GHAE", async (t) => {
await uploadDatabases(
testRepoName,
config,
createFeatureFlags([]),
testApiDetails,
getRecordingLogger(loggedMessages)
);
@@ -195,6 +185,7 @@ test("Abort database upload if not analyzing default branch", async (t) => {
await uploadDatabases(
testRepoName,
getTestConfig(tmpDir),
uploadToUploadsDomainFlags,
testApiDetails,
getRecordingLogger(loggedMessages)
);
@@ -208,7 +199,7 @@ test("Abort database upload if not analyzing default branch", async (t) => {
});
});
test("Abort database upload if opt-in request returns 404", async (t) => {
test("Abort database upload if feature flag is disabled", async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
sinon
@@ -217,8 +208,6 @@ test("Abort database upload if opt-in request returns 404", async (t) => {
.returns("true");
sinon.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
mockHttpRequests(404);
setCodeQL({
async databaseBundle() {
return;
@@ -229,6 +218,7 @@ test("Abort database upload if opt-in request returns 404", async (t) => {
await uploadDatabases(
testRepoName,
getTestConfig(tmpDir),
createFeatureFlags(["uploads_domain_enabled"]),
testApiDetails,
getRecordingLogger(loggedMessages)
);
@@ -243,41 +233,6 @@ test("Abort database upload if opt-in request returns 404", async (t) => {
});
});
test("Abort database upload if opt-in request fails with something other than 404", async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
sinon
.stub(actionsUtil, "getRequiredInput")
.withArgs("upload-database")
.returns("true");
sinon.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
mockHttpRequests(500);
setCodeQL({
async databaseBundle() {
return;
},
});
const loggedMessages = [] as LoggedMessage[];
await uploadDatabases(
testRepoName,
getTestConfig(tmpDir),
testApiDetails,
getRecordingLogger(loggedMessages)
);
t.assert(
loggedMessages.find(
(v) =>
v.type === "info" &&
v.message ===
"Skipping database upload due to unknown error: Error: some error message"
) !== undefined
);
});
});
test("Don't crash if uploading a database fails", async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -287,7 +242,9 @@ test("Don't crash if uploading a database fails", async (t) => {
.returns("true");
sinon.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
mockHttpRequests(200, false, 500);
const featureFlags = createFeatureFlags(["database_uploads_enabled"]);
await mockHttpRequests(featureFlags, 500);
setCodeQL({
async databaseBundle(_: string, outputFilePath: string) {
@@ -299,9 +256,13 @@ test("Don't crash if uploading a database fails", async (t) => {
await uploadDatabases(
testRepoName,
getTestConfig(tmpDir),
featureFlags,
testApiDetails,
getRecordingLogger(loggedMessages)
);
console.log(loggedMessages);
t.assert(
loggedMessages.find(
(v) =>
@@ -322,7 +283,7 @@ test("Successfully uploading a database to api.github.com", async (t) => {
.returns("true");
sinon.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
mockHttpRequests(200, false, 201);
await mockHttpRequests(uploadToUploadsDomainFlags, 201);
setCodeQL({
async databaseBundle(_: string, outputFilePath: string) {
@@ -334,6 +295,7 @@ test("Successfully uploading a database to api.github.com", async (t) => {
await uploadDatabases(
testRepoName,
getTestConfig(tmpDir),
uploadToUploadsDomainFlags,
testApiDetails,
getRecordingLogger(loggedMessages)
);
@@ -356,7 +318,7 @@ test("Successfully uploading a database to uploads.github.com", async (t) => {
.returns("true");
sinon.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
mockHttpRequests(200, true, 201);
await mockHttpRequests(uploadToUploadsDomainFlags, 201);
setCodeQL({
async databaseBundle(_: string, outputFilePath: string) {
@@ -368,6 +330,7 @@ test("Successfully uploading a database to uploads.github.com", async (t) => {
await uploadDatabases(
testRepoName,
getTestConfig(tmpDir),
uploadToUploadsDomainFlags,
testApiDetails,
getRecordingLogger(loggedMessages)
);