Skip to content

Commit

Permalink
Showing 12 changed files with 84 additions and 97 deletions.
4 changes: 2 additions & 2 deletions lib/analyze-action-env.test.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/analyze-action-env.test.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions lib/analyze-action-input.test.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/analyze-action-input.test.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 3 additions & 43 deletions lib/feature-flags.test.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/feature-flags.test.js.map
25 changes: 24 additions & 1 deletion lib/testing-utils.js
2 changes: 1 addition & 1 deletion lib/testing-utils.js.map
10 changes: 7 additions & 3 deletions src/analyze-action-env.test.ts
@@ -4,7 +4,11 @@ import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import * as analyze from "./analyze";
import * as configUtils from "./config-utils";
import { setupTests, setupActionsVars } from "./testing-utils";
import {
setupTests,
setupActionsVars,
mockFeatureFlagApiEndpoint,
} from "./testing-utils";
import * as util from "./util";

setupTests(test);
@@ -25,8 +29,7 @@ test("analyze action with RAM & threads from environment variables", async (t) =
.resolves({} as actionsUtil.StatusReportBase);
sinon.stub(actionsUtil, "sendStatusReport").resolves(true);
sinon.stub(configUtils, "getConfig").resolves({
// Use GHES so we don't try to call the feature flags API endpoint
gitHubVersion: { type: util.GitHubVariant.GHES, version: "3.0.0" },
gitHubVersion: { type: util.GitHubVariant.DOTCOM },
languages: [],
} as unknown as configUtils.Config);
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
@@ -35,6 +38,7 @@ test("analyze action with RAM & threads from environment variables", async (t) =
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
optionalInputStub.withArgs("cleanup-level").returns("none");
setupActionsVars(tmpDir, tmpDir);
mockFeatureFlagApiEndpoint(200, {});

// When there are no action inputs for RAM and threads, the action uses
// environment variables (passed down from the init action) to set RAM and
10 changes: 7 additions & 3 deletions src/analyze-action-input.test.ts
@@ -4,7 +4,11 @@ import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import * as analyze from "./analyze";
import * as configUtils from "./config-utils";
import { setupTests, setupActionsVars } from "./testing-utils";
import {
setupTests,
setupActionsVars,
mockFeatureFlagApiEndpoint,
} from "./testing-utils";
import * as util from "./util";

setupTests(test);
@@ -25,8 +29,7 @@ test("analyze action with RAM & threads from action inputs", async (t) => {
.resolves({} as actionsUtil.StatusReportBase);
sinon.stub(actionsUtil, "sendStatusReport").resolves(true);
sinon.stub(configUtils, "getConfig").resolves({
// Use GHES so we don't try to call the feature flags API endpoint
gitHubVersion: { type: util.GitHubVariant.GHES, version: "3.0.0" },
gitHubVersion: { type: util.GitHubVariant.DOTCOM },
languages: [],
} as unknown as configUtils.Config);
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
@@ -35,6 +38,7 @@ test("analyze action with RAM & threads from action inputs", async (t) => {
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
optionalInputStub.withArgs("cleanup-level").returns("none");
setupActionsVars(tmpDir, tmpDir);
mockFeatureFlagApiEndpoint(200, {});

process.env["CODEQL_THREADS"] = "1";
process.env["CODEQL_RAM"] = "4992";
44 changes: 5 additions & 39 deletions src/feature-flags.test.ts
@@ -1,26 +1,18 @@
import * as github from "@actions/github";
import test from "ava";
import * as sinon from "sinon";

import * as apiClient from "./api-client";
import { GitHubApiDetails } from "./api-client";
import { FeatureFlag, GitHubFeatureFlags } from "./feature-flags";
import { getRunnerLogger } from "./logging";
import { parseRepositoryNwo } from "./repository";
import {
getRecordingLogger,
LoggedMessage,
mockFeatureFlagApiEndpoint,
setupActionsVars,
setupTests,
} from "./testing-utils";
import * as util from "./util";
import {
GitHubVariant,
HTTPError,
initializeEnvironment,
Mode,
withTmpDir,
} from "./util";
import { GitHubVariant, initializeEnvironment, Mode, withTmpDir } from "./util";

setupTests(test);

@@ -35,32 +27,6 @@ const testApiDetails: GitHubApiDetails = {

const testRepositoryNwo = parseRepositoryNwo("github/example");

function mockHttpRequests(
responseStatusCode: number,
flags: { [flagName: string]: boolean }
) {
// 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-action/features"
);
if (responseStatusCode < 300) {
optInSpy.resolves({
status: responseStatusCode,
data: flags,
headers: {},
url: "GET /repos/:owner/:repo/code-scanning/codeql-action/features",
});
} else {
optInSpy.throws(new HTTPError("some error message", responseStatusCode));
}

sinon.stub(apiClient, "getApiClient").value(() => client);
}

const ALL_FEATURE_FLAGS_DISABLED_VARIANTS: Array<{
description: string;
gitHubVersion: util.GitHubVersion;
@@ -113,7 +79,7 @@ test("Feature flags are disabled if they're not returned in API response", async
getRecordingLogger(loggedMessages)
);

mockHttpRequests(200, {});
mockFeatureFlagApiEndpoint(200, {});

for (const flag of Object.values(FeatureFlag)) {
t.assert((await featureFlags.getValue(flag)) === false);
@@ -147,7 +113,7 @@ test("Feature flags exception is propagated if the API request errors", async (t
getRunnerLogger(true)
);

mockHttpRequests(500, {});
mockFeatureFlagApiEndpoint(500, {});

await t.throwsAsync(async () => featureFlags.preloadFeatureFlags(), {
message:
@@ -179,7 +145,7 @@ for (const featureFlag of FEATURE_FLAGS) {
expectedFeatureFlags[f] = false;
}
expectedFeatureFlags[featureFlag] = true;
mockHttpRequests(200, expectedFeatureFlags);
mockFeatureFlagApiEndpoint(200, expectedFeatureFlags);

const actualFeatureFlags = {
database_uploads_enabled: await featureFlags.getValue(
30 changes: 30 additions & 0 deletions src/testing-utils.ts
@@ -1,8 +1,11 @@
import * as github from "@actions/github";
import { TestInterface } from "ava";
import * as sinon from "sinon";

import * as apiClient from "./api-client";
import * as CodeQL from "./codeql";
import { Logger } from "./logging";
import { HTTPError } from "./util";

type TestContext = {
stdoutWrite: any;
@@ -119,3 +122,30 @@ export function getRecordingLogger(messages: LoggedMessage[]): Logger {
endGroup: () => undefined,
};
}

/** Mock the HTTP request to the feature flags enablement API endpoint. */
export function mockFeatureFlagApiEndpoint(
responseStatusCode: number,
response: { [flagName: string]: boolean }
) {
// 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-action/features"
);
if (responseStatusCode < 300) {
optInSpy.resolves({
status: responseStatusCode,
data: response,
headers: {},
url: "GET /repos/:owner/:repo/code-scanning/codeql-action/features",
});
} else {
optInSpy.throws(new HTTPError("some error message", responseStatusCode));
}

sinon.stub(apiClient, "getApiClient").value(() => client);
}

0 comments on commit 254816c

Please sign in to comment.