mirror of
https://github.com/github/codeql-action.git
synced 2026-04-26 00:38:48 +00:00
203 lines
6.4 KiB
TypeScript
203 lines
6.4 KiB
TypeScript
import path from "path";
|
|
|
|
import test from "ava";
|
|
import * as sinon from "sinon";
|
|
|
|
import * as actionsUtil from "./actions-util";
|
|
import {
|
|
AnalysisKind,
|
|
CodeScanning,
|
|
compatibilityMatrix,
|
|
RiskAssessment,
|
|
getAnalysisConfig,
|
|
getAnalysisKinds,
|
|
parseAnalysisKinds,
|
|
supportedAnalysisKinds,
|
|
} from "./analyses";
|
|
import { EnvVar } from "./environment";
|
|
import { getRunnerLogger } from "./logging";
|
|
import { setupTests } from "./testing-utils";
|
|
import { AssessmentPayload } from "./upload-lib/types";
|
|
import { ConfigurationError } from "./util";
|
|
|
|
setupTests(test);
|
|
|
|
test("All known analysis kinds can be parsed successfully", async (t) => {
|
|
for (const analysisKind of supportedAnalysisKinds) {
|
|
t.deepEqual(await parseAnalysisKinds(analysisKind), [analysisKind]);
|
|
}
|
|
});
|
|
|
|
test("Parsing analysis kinds returns unique results", async (t) => {
|
|
const analysisKinds = await parseAnalysisKinds(
|
|
"code-scanning,code-quality,code-scanning",
|
|
);
|
|
t.deepEqual(analysisKinds, [
|
|
AnalysisKind.CodeScanning,
|
|
AnalysisKind.CodeQuality,
|
|
]);
|
|
});
|
|
|
|
test("Parsing an unknown analysis kind fails with a configuration error", async (t) => {
|
|
await t.throwsAsync(parseAnalysisKinds("code-scanning,foo"), {
|
|
instanceOf: ConfigurationError,
|
|
});
|
|
});
|
|
|
|
test("Parsing analysis kinds requires at least one analysis kind", async (t) => {
|
|
await t.throwsAsync(parseAnalysisKinds(","), {
|
|
instanceOf: ConfigurationError,
|
|
});
|
|
});
|
|
|
|
test.serial(
|
|
"getAnalysisKinds - returns expected analysis kinds for `analysis-kinds` input",
|
|
async (t) => {
|
|
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
|
requiredInputStub
|
|
.withArgs("analysis-kinds")
|
|
.returns("code-scanning,code-quality");
|
|
const result = await getAnalysisKinds(getRunnerLogger(true), true);
|
|
t.assert(result.includes(AnalysisKind.CodeScanning));
|
|
t.assert(result.includes(AnalysisKind.CodeQuality));
|
|
},
|
|
);
|
|
|
|
test.serial(
|
|
"getAnalysisKinds - includes `code-quality` when deprecated `quality-queries` input is used",
|
|
async (t) => {
|
|
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
|
requiredInputStub.withArgs("analysis-kinds").returns("code-scanning");
|
|
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
|
|
optionalInputStub.withArgs("quality-queries").returns("code-quality");
|
|
const result = await getAnalysisKinds(getRunnerLogger(true), true);
|
|
t.assert(result.includes(AnalysisKind.CodeScanning));
|
|
t.assert(result.includes(AnalysisKind.CodeQuality));
|
|
},
|
|
);
|
|
|
|
test.serial(
|
|
"getAnalysisKinds - throws if `analysis-kinds` input is invalid",
|
|
async (t) => {
|
|
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
|
requiredInputStub.withArgs("analysis-kinds").returns("no-such-thing");
|
|
await t.throwsAsync(getAnalysisKinds(getRunnerLogger(true), true));
|
|
},
|
|
);
|
|
|
|
// Test the compatibility matrix by looping through all analysis kinds.
|
|
const analysisKinds = Object.values(AnalysisKind);
|
|
for (let i = 0; i < analysisKinds.length; i++) {
|
|
const analysisKind = analysisKinds[i];
|
|
|
|
for (let j = i + 1; j < analysisKinds.length; j++) {
|
|
const otherAnalysis = analysisKinds[j];
|
|
|
|
if (analysisKind === otherAnalysis) continue;
|
|
if (compatibilityMatrix[analysisKind].has(otherAnalysis)) {
|
|
test.serial(
|
|
`getAnalysisKinds - allows ${analysisKind} with ${otherAnalysis}`,
|
|
async (t) => {
|
|
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
|
requiredInputStub
|
|
.withArgs("analysis-kinds")
|
|
.returns([analysisKind, otherAnalysis].join(","));
|
|
const result = await getAnalysisKinds(getRunnerLogger(true), true);
|
|
t.is(result.length, 2);
|
|
},
|
|
);
|
|
} else {
|
|
test.serial(
|
|
`getAnalysisKinds - throws if ${analysisKind} is enabled with ${otherAnalysis}`,
|
|
async (t) => {
|
|
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
|
requiredInputStub
|
|
.withArgs("analysis-kinds")
|
|
.returns([analysisKind, otherAnalysis].join(","));
|
|
await t.throwsAsync(getAnalysisKinds(getRunnerLogger(true), true), {
|
|
instanceOf: ConfigurationError,
|
|
message: `${analysisKind} and ${otherAnalysis} cannot be enabled at the same time`,
|
|
});
|
|
},
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
test("Code Scanning configuration does not accept other SARIF extensions", (t) => {
|
|
for (const analysisKind of supportedAnalysisKinds) {
|
|
if (analysisKind === AnalysisKind.CodeScanning) continue;
|
|
|
|
const analysis = getAnalysisConfig(analysisKind);
|
|
const sarifPath = path.join("path", "to", `file${analysis.sarifExtension}`);
|
|
|
|
// The Code Scanning configuration's `sarifPredicate` should not accept a path which
|
|
// ends in a different configuration's `sarifExtension`.
|
|
t.false(CodeScanning.sarifPredicate(sarifPath));
|
|
}
|
|
});
|
|
|
|
test.serial(
|
|
"Risk Assessment configuration transforms SARIF upload payload",
|
|
(t) => {
|
|
process.env[EnvVar.RISK_ASSESSMENT_ID] = "1";
|
|
const payload = RiskAssessment.transformPayload({
|
|
commit_oid: "abc",
|
|
sarif: "sarif",
|
|
ref: "ref",
|
|
workflow_run_attempt: 1,
|
|
workflow_run_id: 1,
|
|
checkout_uri: "uri",
|
|
tool_names: [],
|
|
}) as AssessmentPayload;
|
|
|
|
const expected: AssessmentPayload = { sarif: "sarif", assessment_id: 1 };
|
|
t.deepEqual(expected, payload);
|
|
},
|
|
);
|
|
|
|
test.serial(
|
|
"Risk Assessment configuration throws for negative assessment IDs",
|
|
(t) => {
|
|
process.env[EnvVar.RISK_ASSESSMENT_ID] = "-1";
|
|
t.throws(
|
|
() =>
|
|
RiskAssessment.transformPayload({
|
|
commit_oid: "abc",
|
|
sarif: "sarif",
|
|
ref: "ref",
|
|
workflow_run_attempt: 1,
|
|
workflow_run_id: 1,
|
|
checkout_uri: "uri",
|
|
tool_names: [],
|
|
}),
|
|
{
|
|
instanceOf: Error,
|
|
message: (msg) =>
|
|
msg.startsWith(`${EnvVar.RISK_ASSESSMENT_ID} must not be negative: `),
|
|
},
|
|
);
|
|
},
|
|
);
|
|
|
|
test.serial("Risk Assessment configuration throws for invalid IDs", (t) => {
|
|
process.env[EnvVar.RISK_ASSESSMENT_ID] = "foo";
|
|
t.throws(
|
|
() =>
|
|
RiskAssessment.transformPayload({
|
|
commit_oid: "abc",
|
|
sarif: "sarif",
|
|
ref: "ref",
|
|
workflow_run_attempt: 1,
|
|
workflow_run_id: 1,
|
|
checkout_uri: "uri",
|
|
tool_names: [],
|
|
}),
|
|
{
|
|
instanceOf: Error,
|
|
message: (msg) =>
|
|
msg.startsWith(`${EnvVar.RISK_ASSESSMENT_ID} must not be NaN: `),
|
|
},
|
|
);
|
|
});
|