Fix some tests that should be serial

This commit is contained in:
Henry Mercer
2026-03-04 17:58:13 +01:00
parent 759b5db350
commit 6d1c37ed8f
+169 -154
View File
@@ -139,7 +139,7 @@ function mockListLanguages(languages: string[]) {
sinon.stub(api, "getApiClient").value(() => client);
}
test("load empty config", async (t) => {
test.serial("load empty config", async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = getRunnerLogger(true);
const languages = "javascript,python";
@@ -180,7 +180,7 @@ test("load empty config", async (t) => {
});
});
test("load code quality config", async (t) => {
test.serial("load code quality config", async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = getRunnerLogger(true);
const languages = "actions";
@@ -230,65 +230,68 @@ test("load code quality config", async (t) => {
});
});
test("initActionState doesn't throw if there are queries configured in the repository properties", async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = getRunnerLogger(true);
const languages = "javascript";
test.serial(
"initActionState doesn't throw if there are queries configured in the repository properties",
async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = getRunnerLogger(true);
const languages = "javascript";
const codeql = createStubCodeQL({
async betterResolveLanguages() {
return {
extractors: {
javascript: [{ extractor_root: "" }],
},
};
},
const codeql = createStubCodeQL({
async betterResolveLanguages() {
return {
extractors: {
javascript: [{ extractor_root: "" }],
},
};
},
});
// This should be ignored and no error should be thrown.
const repositoryProperties = {
"github-codeql-extra-queries": "+foo",
};
// Expected configuration for a CQ-only analysis.
const computedConfig: UserConfig = {
"disable-default-queries": true,
queries: [{ uses: "code-quality" }],
"query-filters": [],
};
const expectedConfig = createTestConfig({
analysisKinds: [AnalysisKind.CodeQuality],
languages: [KnownLanguage.javascript],
codeQLCmd: codeql.getPath(),
computedConfig,
dbLocation: path.resolve(tempDir, "codeql_databases"),
debugArtifactName: "",
debugDatabaseName: "",
tempDir,
repositoryProperties,
});
await t.notThrowsAsync(async () => {
const config = await configUtils.initConfig(
createFeatures([]),
createTestInitConfigInputs({
analysisKinds: [AnalysisKind.CodeQuality],
languagesInput: languages,
repository: { owner: "github", repo: "example" },
tempDir,
codeql,
repositoryProperties,
logger,
}),
);
t.deepEqual(config, expectedConfig);
});
});
},
);
// This should be ignored and no error should be thrown.
const repositoryProperties = {
"github-codeql-extra-queries": "+foo",
};
// Expected configuration for a CQ-only analysis.
const computedConfig: UserConfig = {
"disable-default-queries": true,
queries: [{ uses: "code-quality" }],
"query-filters": [],
};
const expectedConfig = createTestConfig({
analysisKinds: [AnalysisKind.CodeQuality],
languages: [KnownLanguage.javascript],
codeQLCmd: codeql.getPath(),
computedConfig,
dbLocation: path.resolve(tempDir, "codeql_databases"),
debugArtifactName: "",
debugDatabaseName: "",
tempDir,
repositoryProperties,
});
await t.notThrowsAsync(async () => {
const config = await configUtils.initConfig(
createFeatures([]),
createTestInitConfigInputs({
analysisKinds: [AnalysisKind.CodeQuality],
languagesInput: languages,
repository: { owner: "github", repo: "example" },
tempDir,
codeql,
repositoryProperties,
logger,
}),
);
t.deepEqual(config, expectedConfig);
});
});
});
test("loading a saved config produces the same config", async (t) => {
test.serial("loading a saved config produces the same config", async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = getRunnerLogger(true);
@@ -335,7 +338,7 @@ test("loading a saved config produces the same config", async (t) => {
});
});
test("loading config with version mismatch throws", async (t) => {
test.serial("loading config with version mismatch throws", async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = getRunnerLogger(true);
@@ -387,7 +390,7 @@ test("loading config with version mismatch throws", async (t) => {
});
});
test("load input outside of workspace", async (t) => {
test.serial("load input outside of workspace", async (t) => {
return await withTmpDir(async (tempDir) => {
try {
await configUtils.initConfig(
@@ -412,7 +415,7 @@ test("load input outside of workspace", async (t) => {
});
});
test("load non-local input with invalid repo syntax", async (t) => {
test.serial("load non-local input with invalid repo syntax", async (t) => {
return await withTmpDir(async (tempDir) => {
// no filename given, just a repo
const configFile = "octo-org/codeql-config@main";
@@ -440,7 +443,7 @@ test("load non-local input with invalid repo syntax", async (t) => {
});
});
test("load non-existent input", async (t) => {
test.serial("load non-existent input", async (t) => {
return await withTmpDir(async (tempDir) => {
const languagesInput = "javascript";
const configFile = "input";
@@ -470,7 +473,7 @@ test("load non-existent input", async (t) => {
});
});
test("load non-empty input", async (t) => {
test.serial("load non-empty input", async (t) => {
return await withTmpDir(async (tempDir) => {
const codeql = createStubCodeQL({
async betterResolveLanguages() {
@@ -541,18 +544,20 @@ test("load non-empty input", async (t) => {
});
});
test("Using config input and file together, config input should be used.", async (t) => {
return await withTmpDir(async (tempDir) => {
process.env["RUNNER_TEMP"] = tempDir;
process.env["GITHUB_WORKSPACE"] = tempDir;
test.serial(
"Using config input and file together, config input should be used.",
async (t) => {
return await withTmpDir(async (tempDir) => {
process.env["RUNNER_TEMP"] = tempDir;
process.env["GITHUB_WORKSPACE"] = tempDir;
const inputFileContents = `
const inputFileContents = `
name: my config
queries:
- uses: ./foo_file`;
const configFilePath = createConfigFile(inputFileContents, tempDir);
const configFilePath = createConfigFile(inputFileContents, tempDir);
const configInput = `
const configInput = `
name: my config
queries:
- uses: ./foo
@@ -563,39 +568,40 @@ test("Using config input and file together, config input should be used.", async
- c/d@1.2.3
`;
fs.mkdirSync(path.join(tempDir, "foo"));
fs.mkdirSync(path.join(tempDir, "foo"));
const codeql = createStubCodeQL({
async betterResolveLanguages() {
return {
extractors: {
javascript: [{ extractor_root: "" }],
python: [{ extractor_root: "" }],
},
};
},
const codeql = createStubCodeQL({
async betterResolveLanguages() {
return {
extractors: {
javascript: [{ extractor_root: "" }],
python: [{ extractor_root: "" }],
},
};
},
});
// Only JS, python packs will be ignored
const languagesInput = "javascript";
const config = await configUtils.initConfig(
createFeatures([]),
createTestInitConfigInputs({
languagesInput,
configFile: configFilePath,
configInput,
tempDir,
codeql,
workspacePath: tempDir,
}),
);
t.deepEqual(config.originalUserInput, yaml.load(configInput));
});
},
);
// Only JS, python packs will be ignored
const languagesInput = "javascript";
const config = await configUtils.initConfig(
createFeatures([]),
createTestInitConfigInputs({
languagesInput,
configFile: configFilePath,
configInput,
tempDir,
codeql,
workspacePath: tempDir,
}),
);
t.deepEqual(config.originalUserInput, yaml.load(configInput));
});
});
test("API client used when reading remote config", async (t) => {
test.serial("API client used when reading remote config", async (t) => {
return await withTmpDir(async (tempDir) => {
const codeql = createStubCodeQL({
async betterResolveLanguages() {
@@ -644,34 +650,37 @@ test("API client used when reading remote config", async (t) => {
});
});
test("Remote config handles the case where a directory is provided", async (t) => {
return await withTmpDir(async (tempDir) => {
const dummyResponse = []; // directories are returned as arrays
mockGetContents(dummyResponse);
test.serial(
"Remote config handles the case where a directory is provided",
async (t) => {
return await withTmpDir(async (tempDir) => {
const dummyResponse = []; // directories are returned as arrays
mockGetContents(dummyResponse);
const repoReference = "octo-org/codeql-config/config.yaml@main";
try {
await configUtils.initConfig(
createFeatures([]),
createTestInitConfigInputs({
configFile: repoReference,
tempDir,
workspacePath: tempDir,
}),
);
throw new Error("initConfig did not throw error");
} catch (err) {
t.deepEqual(
err,
new ConfigurationError(
errorMessages.getConfigFileDirectoryGivenMessage(repoReference),
),
);
}
});
});
const repoReference = "octo-org/codeql-config/config.yaml@main";
try {
await configUtils.initConfig(
createFeatures([]),
createTestInitConfigInputs({
configFile: repoReference,
tempDir,
workspacePath: tempDir,
}),
);
throw new Error("initConfig did not throw error");
} catch (err) {
t.deepEqual(
err,
new ConfigurationError(
errorMessages.getConfigFileDirectoryGivenMessage(repoReference),
),
);
}
});
},
);
test("Invalid format of remote config handled correctly", async (t) => {
test.serial("Invalid format of remote config handled correctly", async (t) => {
return await withTmpDir(async (tempDir) => {
const dummyResponse = {
// note no "content" property here
@@ -700,7 +709,7 @@ test("Invalid format of remote config handled correctly", async (t) => {
});
});
test("No detected languages", async (t) => {
test.serial("No detected languages", async (t) => {
return await withTmpDir(async (tempDir) => {
mockListLanguages([]);
const codeql = createStubCodeQL({
@@ -728,7 +737,7 @@ test("No detected languages", async (t) => {
});
});
test("Unknown languages", async (t) => {
test.serial("Unknown languages", async (t) => {
return await withTmpDir(async (tempDir) => {
const languagesInput = "rubbish,english";
@@ -755,7 +764,7 @@ test("Unknown languages", async (t) => {
const mockLogger = getRunnerLogger(true);
test("no generateRegistries when registries is undefined", async (t) => {
test.serial("no generateRegistries when registries is undefined", async (t) => {
return await withTmpDir(async (tmpDir) => {
const registriesInput = undefined;
const logger = getRunnerLogger(true);
@@ -767,24 +776,27 @@ test("no generateRegistries when registries is undefined", async (t) => {
});
});
test("generateRegistries prefers original CODEQL_REGISTRIES_AUTH", async (t) => {
return await withTmpDir(async (tmpDir) => {
process.env.CODEQL_REGISTRIES_AUTH = "original";
const registriesInput = yaml.dump([
{
url: "http://ghcr.io",
packages: ["codeql/*", "codeql-testing/*"],
token: "not-a-token",
},
]);
const logger = getRunnerLogger(true);
const { registriesAuthTokens, qlconfigFile } =
await configUtils.generateRegistries(registriesInput, tmpDir, logger);
test.serial(
"generateRegistries prefers original CODEQL_REGISTRIES_AUTH",
async (t) => {
return await withTmpDir(async (tmpDir) => {
process.env.CODEQL_REGISTRIES_AUTH = "original";
const registriesInput = yaml.dump([
{
url: "http://ghcr.io",
packages: ["codeql/*", "codeql-testing/*"],
token: "not-a-token",
},
]);
const logger = getRunnerLogger(true);
const { registriesAuthTokens, qlconfigFile } =
await configUtils.generateRegistries(registriesInput, tmpDir, logger);
t.is(registriesAuthTokens, "original");
t.is(qlconfigFile, path.join(tmpDir, "qlconfig.yml"));
});
});
t.is(registriesAuthTokens, "original");
t.is(qlconfigFile, path.join(tmpDir, "qlconfig.yml"));
});
},
);
// getLanguages
@@ -862,7 +874,7 @@ const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
expectedLanguages: ["javascript"],
},
].forEach((args) => {
test(`getLanguages: ${args.name}`, async (t) => {
test.serial(`getLanguages: ${args.name}`, async (t) => {
const mockRequest = mockLanguagesInRepo(args.languagesInRepository);
const stubExtractorEntry = {
extractor_root: "",
@@ -1999,13 +2011,16 @@ for (const language in KnownLanguage) {
);
}
test("hasActionsWorkflows doesn't throw if workflows folder doesn't exist", async (t) => {
return withTmpDir(async (tmpDir) => {
t.notThrows(() => configUtils.hasActionsWorkflows(tmpDir));
});
});
test.serial(
"hasActionsWorkflows doesn't throw if workflows folder doesn't exist",
async (t) => {
return withTmpDir(async (tmpDir) => {
t.notThrows(() => configUtils.hasActionsWorkflows(tmpDir));
});
},
);
test("getPrimaryAnalysisConfig - single analysis kind", (t) => {
test.serial("getPrimaryAnalysisConfig - single analysis kind", (t) => {
// If only one analysis kind is configured, we expect to get the matching configuration.
for (const analysisKind of supportedAnalysisKinds) {
const singleKind = createTestConfig({ analysisKinds: [analysisKind] });
@@ -2013,7 +2028,7 @@ test("getPrimaryAnalysisConfig - single analysis kind", (t) => {
}
});
test("getPrimaryAnalysisConfig - Code Scanning + Code Quality", (t) => {
test.serial("getPrimaryAnalysisConfig - Code Scanning + Code Quality", (t) => {
// For CS+CQ, we expect to get the Code Scanning configuration.
const codeScanningAndCodeQuality = createTestConfig({
analysisKinds: [AnalysisKind.CodeScanning, AnalysisKind.CodeQuality],