Skip to content

Commit abfb9f4

Browse files
committed
Add checkPacksForOverlayCompatibility()
1 parent 9a9af90 commit abfb9f4

File tree

2 files changed

+400
-2
lines changed

2 files changed

+400
-2
lines changed

src/init.test.ts

Lines changed: 291 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import * as fs from "fs";
22
import path from "path";
33

4-
import test from "ava";
4+
import test, { ExecutionContext } from "ava";
55

6-
import { cleanupDatabaseClusterDirectory } from "./init";
6+
import { setCodeQL } from "./codeql";
7+
import {
8+
checkPacksForOverlayCompatibility,
9+
cleanupDatabaseClusterDirectory,
10+
} from "./init";
11+
import { Language } from "./languages";
712
import {
813
LoggedMessage,
914
createTestConfig,
@@ -106,3 +111,287 @@ for (const { runnerEnv, ErrorConstructor, message } of [
106111
});
107112
});
108113
}
114+
115+
type PackInfo = {
116+
language: Language;
117+
packinfoContents: string | undefined;
118+
sourceOnlyPack?: boolean;
119+
};
120+
121+
const testCheckPacksForOverlayCompatibility = test.macro({
122+
exec: async (
123+
t: ExecutionContext,
124+
_title: string,
125+
{
126+
cliOverlayVersion,
127+
languages,
128+
packs,
129+
expectedResult,
130+
}: {
131+
cliOverlayVersion: number | undefined;
132+
languages: Language[];
133+
packs: Record<string, PackInfo>;
134+
expectedResult: boolean;
135+
},
136+
) => {
137+
await withTmpDir(async (tmpDir) => {
138+
const packDirsByLanguage = new Map<Language, string[]>();
139+
140+
for (const [packName, packInfo] of Object.entries(packs)) {
141+
const packPath = path.join(tmpDir, packName);
142+
fs.mkdirSync(packPath, { recursive: true });
143+
if (packInfo.packinfoContents) {
144+
fs.writeFileSync(
145+
path.join(packPath, ".packinfo"),
146+
packInfo.packinfoContents,
147+
);
148+
}
149+
fs.writeFileSync(
150+
path.join(packPath, "qlpack.yml"),
151+
packInfo.sourceOnlyPack
152+
? `name: ${packName}\nversion: 1.0.0\n`
153+
: `name: ${packName}\nversion: 1.0.0\nbuildMetadata:\n sha: 123abc\n`,
154+
);
155+
156+
if (!packDirsByLanguage.has(packInfo.language)) {
157+
packDirsByLanguage.set(packInfo.language, []);
158+
}
159+
packDirsByLanguage.get(packInfo.language)!.push(packPath);
160+
}
161+
162+
const codeql = setCodeQL({
163+
getVersion: async () => ({
164+
version: "2.22.2",
165+
overlayVersion: cliOverlayVersion,
166+
}),
167+
resolveQueriesStartingPacks: async (suitePaths: string[]) => {
168+
for (const language of packDirsByLanguage.keys()) {
169+
const suiteForLanguage = path.join(
170+
language,
171+
"temp",
172+
"config-queries.qls",
173+
);
174+
if (suitePaths[0].endsWith(suiteForLanguage)) {
175+
return packDirsByLanguage.get(language) || [];
176+
}
177+
}
178+
return [];
179+
},
180+
});
181+
182+
const messages: LoggedMessage[] = [];
183+
const result = await checkPacksForOverlayCompatibility(
184+
codeql,
185+
createTestConfig({ dbLocation: tmpDir, languages }),
186+
getRecordingLogger(messages),
187+
);
188+
t.is(result, expectedResult);
189+
t.deepEqual(
190+
messages.length,
191+
expectedResult ? 0 : 1,
192+
"Expected log messages",
193+
);
194+
});
195+
},
196+
title: (_, title) => `checkPacksForOverlayCompatibility: ${title}`,
197+
});
198+
199+
test(
200+
testCheckPacksForOverlayCompatibility,
201+
"returns false when CLI does not support overlay",
202+
{
203+
cliOverlayVersion: undefined,
204+
languages: [Language.java],
205+
packs: {
206+
"codeql/java-queries": {
207+
language: Language.java,
208+
packinfoContents: '{"overlayVersion":2}',
209+
},
210+
},
211+
expectedResult: false,
212+
},
213+
);
214+
215+
test(
216+
testCheckPacksForOverlayCompatibility,
217+
"returns true when there are no query packs",
218+
{
219+
cliOverlayVersion: 2,
220+
languages: [Language.java],
221+
packs: {},
222+
expectedResult: true,
223+
},
224+
);
225+
226+
test(
227+
testCheckPacksForOverlayCompatibility,
228+
"returns true when query pack has not been compiled",
229+
{
230+
cliOverlayVersion: 2,
231+
languages: [Language.java],
232+
packs: {
233+
"codeql/java-queries": {
234+
language: Language.java,
235+
packinfoContents: undefined,
236+
sourceOnlyPack: true,
237+
},
238+
},
239+
expectedResult: true,
240+
},
241+
);
242+
243+
test(
244+
testCheckPacksForOverlayCompatibility,
245+
"returns true when query pack has expected overlay version",
246+
{
247+
cliOverlayVersion: 2,
248+
languages: [Language.java],
249+
packs: {
250+
"codeql/java-queries": {
251+
language: Language.java,
252+
packinfoContents: '{"overlayVersion":2}',
253+
},
254+
},
255+
expectedResult: true,
256+
},
257+
);
258+
259+
test(
260+
testCheckPacksForOverlayCompatibility,
261+
"returns true when query packs for all languages to analyze are compatible",
262+
{
263+
cliOverlayVersion: 2,
264+
languages: [Language.cpp, Language.java],
265+
packs: {
266+
"codeql/cpp-queries": {
267+
language: Language.cpp,
268+
packinfoContents: '{"overlayVersion":2}',
269+
},
270+
"codeql/java-queries": {
271+
language: Language.java,
272+
packinfoContents: '{"overlayVersion":2}',
273+
},
274+
},
275+
expectedResult: true,
276+
},
277+
);
278+
279+
test(
280+
testCheckPacksForOverlayCompatibility,
281+
"returns true when query pack for a language not analyzed is incompatible",
282+
{
283+
cliOverlayVersion: 2,
284+
languages: [Language.java],
285+
packs: {
286+
"codeql/cpp-queries": {
287+
language: Language.cpp,
288+
packinfoContents: undefined,
289+
},
290+
"codeql/java-queries": {
291+
language: Language.java,
292+
packinfoContents: '{"overlayVersion":2}',
293+
},
294+
},
295+
expectedResult: true,
296+
},
297+
);
298+
299+
test(
300+
testCheckPacksForOverlayCompatibility,
301+
"returns false when query pack for a language to analyze is incompatible",
302+
{
303+
cliOverlayVersion: 2,
304+
languages: [Language.cpp, Language.java],
305+
packs: {
306+
"codeql/cpp-queries": {
307+
language: Language.cpp,
308+
packinfoContents: '{"overlayVersion":1}',
309+
},
310+
"codeql/java-queries": {
311+
language: Language.java,
312+
packinfoContents: '{"overlayVersion":2}',
313+
},
314+
},
315+
expectedResult: false,
316+
},
317+
);
318+
319+
test(
320+
testCheckPacksForOverlayCompatibility,
321+
"returns false when query pack is missing .packinfo",
322+
{
323+
cliOverlayVersion: 2,
324+
languages: [Language.java],
325+
packs: {
326+
"codeql/java-queries": {
327+
language: Language.java,
328+
packinfoContents: '{"overlayVersion":2}',
329+
},
330+
"custom/queries": {
331+
language: Language.java,
332+
packinfoContents: undefined,
333+
},
334+
},
335+
expectedResult: false,
336+
},
337+
);
338+
339+
test(
340+
testCheckPacksForOverlayCompatibility,
341+
"returns false when query pack has different overlay version",
342+
{
343+
cliOverlayVersion: 2,
344+
languages: [Language.java],
345+
packs: {
346+
"codeql/java-queries": {
347+
language: Language.java,
348+
packinfoContents: '{"overlayVersion":2}',
349+
},
350+
"custom/queries": {
351+
language: Language.java,
352+
packinfoContents: '{"overlayVersion":1}',
353+
},
354+
},
355+
expectedResult: false,
356+
},
357+
);
358+
359+
test(
360+
testCheckPacksForOverlayCompatibility,
361+
"returns false when query pack is missing overlayVersion in .packinfo",
362+
{
363+
cliOverlayVersion: 2,
364+
languages: [Language.java],
365+
packs: {
366+
"codeql/java-queries": {
367+
language: Language.java,
368+
packinfoContents: '{"overlayVersion":2}',
369+
},
370+
"custom/queries": {
371+
language: Language.java,
372+
packinfoContents: "{}",
373+
},
374+
},
375+
expectedResult: false,
376+
},
377+
);
378+
379+
test(
380+
testCheckPacksForOverlayCompatibility,
381+
"returns false when .packinfo is not valid JSON",
382+
{
383+
cliOverlayVersion: 2,
384+
languages: [Language.java],
385+
packs: {
386+
"codeql/java-queries": {
387+
language: Language.java,
388+
packinfoContents: '{"overlayVersion":2}',
389+
},
390+
"custom/queries": {
391+
language: Language.java,
392+
packinfoContents: "this_is_not_valid_json",
393+
},
394+
},
395+
expectedResult: false,
396+
},
397+
);

0 commit comments

Comments
 (0)