Files
codeql-action/src/start-proxy/environment.test.ts
T
Michael B. Gale 99fcc7b2a1 Check whether value is a URL in checkEnvVar and clear credentials
Note also that we run this after `getCredentials` which already instructs Actions to mask credentials that we know about in logs
2026-02-17 13:42:51 +00:00

196 lines
5.5 KiB
TypeScript

import * as fs from "fs";
import * as os from "os";
import path from "path";
import test, { ExecutionContext } from "ava";
import { JavaEnvVars, KnownLanguage } from "../languages";
import {
checkExpectedLogMessages,
getRecordingLogger,
LoggedMessage,
setupTests,
} from "../testing-utils";
import { withTmpDir } from "../util";
import {
checkJavaEnvVars,
checkJdkSettings,
checkProxyEnvironment,
checkProxyEnvVars,
discoverActionsJdks,
JAVA_PROXY_ENV_VARS,
ProxyEnvVars,
} from "./environment";
setupTests(test);
function assertEnvVarLogMessages(
t: ExecutionContext<any>,
envVars: string[],
messages: LoggedMessage[],
expectSet: boolean | string,
) {
const template = (envVar: string) => {
if (typeof expectSet === "string") {
return `Environment variable '${envVar}' is set to '${expectSet}'`;
}
return expectSet
? `Environment variable '${envVar}' is set to '${envVar}'`
: `Environment variable '${envVar}' is not set`;
};
const expected: string[] = [];
for (const envVar of envVars) {
expected.push(template(envVar));
}
checkExpectedLogMessages(t, messages, expected);
}
test("checkJavaEnvironment - none set", (t) => {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
checkJavaEnvVars(logger);
assertEnvVarLogMessages(t, JAVA_PROXY_ENV_VARS, messages, false);
});
test("checkJavaEnvironment - logs values when variables are set", (t) => {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
for (const envVar of Object.values(JavaEnvVars)) {
process.env[envVar] = envVar;
}
checkJavaEnvVars(logger);
assertEnvVarLogMessages(t, JAVA_PROXY_ENV_VARS, messages, true);
});
test("discoverActionsJdks - discovers JDK paths", (t) => {
// Clear GHA variables that may interfere with this test in CI.
for (const envVar of Object.keys(process.env)) {
if (envVar.startsWith("JAVA_HOME_")) {
delete process[envVar];
}
}
const jdk8 = "/usr/lib/jvm/temurin-8-jdk-amd64";
const jdk17 = "/usr/lib/jvm/temurin-17-jdk-amd64";
const jdk21 = "/usr/lib/jvm/temurin-21-jdk-amd64";
process.env[JavaEnvVars.JAVA_HOME] = jdk17;
process.env["JAVA_HOME_8_X64"] = jdk8;
process.env["JAVA_HOME_17_X64"] = jdk17;
process.env["JAVA_HOME_21_X64"] = jdk21;
const results = discoverActionsJdks();
t.is(results.size, 3);
t.true(results.has(jdk8));
t.true(results.has(jdk17));
t.true(results.has(jdk21));
});
test("checkJdkSettings - does not throw for an empty directory", async (t) => {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
await withTmpDir(async (tmpDir) => {
t.notThrows(() => checkJdkSettings(logger, tmpDir));
});
});
test("checkJdkSettings - finds files and logs relevant properties", async (t) => {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
await withTmpDir(async (tmpDir) => {
const dir = path.join(tmpDir, "conf");
fs.mkdirSync(dir);
const file = path.join(dir, "net.properties");
fs.writeFileSync(
file,
[
"irrelevant.property=foo",
"http.proxyHost=proxy.example.com",
"http.unrelated=bar",
].join(os.EOL),
{},
);
checkJdkSettings(logger, tmpDir);
checkExpectedLogMessages(t, messages, [
`Found '${file}'.`,
`Found 'http.proxyHost=proxy.example.com' in '${file}'`,
]);
});
});
test("checkProxyEnvVars - none set", (t) => {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
checkProxyEnvVars(logger);
assertEnvVarLogMessages(t, Object.values(ProxyEnvVars), messages, false);
});
test("checkProxyEnvVars - logs values when variables are set", (t) => {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
for (const envVar of Object.values(ProxyEnvVars)) {
process.env[envVar] = envVar;
}
checkProxyEnvVars(logger);
assertEnvVarLogMessages(t, Object.values(ProxyEnvVars), messages, true);
});
test("checkProxyEnvVars - credentials are removed from URLs", (t) => {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
for (const envVar of Object.values(ProxyEnvVars)) {
process.env[envVar] = "https://secret:password@proxy.local";
}
checkProxyEnvVars(logger);
assertEnvVarLogMessages(
t,
Object.values(ProxyEnvVars),
messages,
"https://proxy.local/",
);
});
test("checkProxyEnvironment - includes base checks for all known languages", (t) => {
for (const language of Object.values(KnownLanguage)) {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
checkProxyEnvironment(logger, language);
assertEnvVarLogMessages(t, Object.keys(ProxyEnvVars), messages, false);
}
});
test("checkProxyEnvironment - includes Java checks for Java", (t) => {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
checkProxyEnvironment(logger, KnownLanguage.java);
assertEnvVarLogMessages(t, Object.keys(ProxyEnvVars), messages, false);
assertEnvVarLogMessages(t, JAVA_PROXY_ENV_VARS, messages, false);
});
test("checkProxyEnvironment - includes language-specific checks if the language is undefined", (t) => {
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
checkProxyEnvironment(logger, undefined);
assertEnvVarLogMessages(t, Object.keys(ProxyEnvVars), messages, false);
assertEnvVarLogMessages(t, JAVA_PROXY_ENV_VARS, messages, false);
});