2020-05-05 17:32:58 +01:00
"use strict" ;
2021-07-27 17:59:59 +01:00
var _ _createBinding = ( this && this . _ _createBinding ) || ( Object . create ? ( function ( o , m , k , k2 ) {
if ( k2 === undefined ) k2 = k ;
2023-01-18 20:00:33 +00:00
var desc = Object . getOwnPropertyDescriptor ( m , k ) ;
if ( ! desc || ( "get" in desc ? ! m . _ _esModule : desc . writable || desc . configurable ) ) {
desc = { enumerable : true , get : function ( ) { return m [ k ] ; } } ;
}
Object . defineProperty ( o , k2 , desc ) ;
2021-07-27 17:59:59 +01:00
} ) : ( function ( o , m , k , k2 ) {
if ( k2 === undefined ) k2 = k ;
o [ k2 ] = m [ k ] ;
} ) ) ;
var _ _setModuleDefault = ( this && this . _ _setModuleDefault ) || ( Object . create ? ( function ( o , v ) {
Object . defineProperty ( o , "default" , { enumerable : true , value : v } ) ;
} ) : function ( o , v ) {
o [ "default" ] = v ;
} ) ;
2020-05-05 17:32:58 +01:00
var _ _importStar = ( this && this . _ _importStar ) || function ( mod ) {
if ( mod && mod . _ _esModule ) return mod ;
var result = { } ;
2021-07-27 17:59:59 +01:00
if ( mod != null ) for ( var k in mod ) if ( k !== "default" && Object . prototype . hasOwnProperty . call ( mod , k ) ) _ _createBinding ( result , mod , k ) ;
_ _setModuleDefault ( result , mod ) ;
2020-05-05 17:32:58 +01:00
return result ;
} ;
2020-06-24 14:12:36 +01:00
var _ _importDefault = ( this && this . _ _importDefault ) || function ( mod ) {
return ( mod && mod . _ _esModule ) ? mod : { "default" : mod } ;
} ;
2020-05-05 17:32:58 +01:00
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
const fs = _ _importStar ( require ( "fs" ) ) ;
const path = _ _importStar ( require ( "path" ) ) ;
2020-10-01 11:03:30 +01:00
const github = _ _importStar ( require ( "@actions/github" ) ) ;
2020-09-29 14:43:37 +01:00
const ava _1 = _ _importDefault ( require ( "ava" ) ) ;
2022-08-29 12:57:46 -07:00
const yaml = _ _importStar ( require ( "js-yaml" ) ) ;
2021-08-11 13:14:56 +01:00
const sinon = _ _importStar ( require ( "sinon" ) ) ;
2020-10-01 11:03:30 +01:00
const api = _ _importStar ( require ( "./api-client" ) ) ;
2020-08-19 15:54:23 +01:00
const codeql _1 = require ( "./codeql" ) ;
2020-10-01 11:03:30 +01:00
const configUtils = _ _importStar ( require ( "./config-utils" ) ) ;
2021-12-15 13:34:29 +00:00
const feature _flags _1 = require ( "./feature-flags" ) ;
2020-08-17 13:34:55 +01:00
const languages _1 = require ( "./languages" ) ;
2020-08-25 16:19:15 +01:00
const logging _1 = require ( "./logging" ) ;
2022-11-23 16:16:02 -08:00
const repository _1 = require ( "./repository" ) ;
2020-06-22 12:12:14 +01:00
const testing _utils _1 = require ( "./testing-utils" ) ;
2023-07-11 11:05:40 +01:00
const util _1 = require ( "./util" ) ;
2021-09-10 13:53:13 -07:00
( 0 , testing _utils _1 . setupTests ) ( ava _1 . default ) ;
2020-11-23 14:18:05 +00:00
const sampleApiDetails = {
auth : "token" ,
2021-01-04 12:31:55 +00:00
externalRepoAuth : "token" ,
2020-11-23 14:18:05 +00:00
url : "https://github.example.com" ,
2022-08-10 21:11:50 +01:00
apiURL : undefined ,
2022-08-29 12:57:46 -07:00
registriesAuthTokens : undefined ,
2020-11-23 14:18:05 +00:00
} ;
2023-07-11 11:05:40 +01:00
const gitHubVersion = { type : util _1 . GitHubVariant . DOTCOM } ;
2020-09-08 10:00:16 +01:00
// Returns the filepath of the newly-created file
function createConfigFile ( inputFileContents , tmpDir ) {
2020-09-14 10:44:43 +01:00
const configFilePath = path . join ( tmpDir , "input" ) ;
fs . writeFileSync ( configFilePath , inputFileContents , "utf8" ) ;
2020-09-08 10:00:16 +01:00
return configFilePath ;
2020-08-28 17:20:40 +01:00
}
2020-07-07 18:32:29 +01:00
function mockGetContents ( content ) {
// Passing an auth token is required, so we just use a dummy value
2020-09-18 15:40:23 +01:00
const client = github . getOctokit ( "123" ) ;
2020-07-07 18:32:29 +01:00
const response = {
2020-09-14 10:44:43 +01:00
data : content ,
2020-07-07 18:32:29 +01:00
} ;
2021-08-11 13:14:56 +01:00
const spyGetContents = sinon
2023-07-13 11:17:33 +01:00
. stub ( client . rest . repos , "getContent" )
2023-01-18 20:22:33 +00:00
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
2020-09-14 10:44:43 +01:00
. resolves ( response ) ;
2021-08-11 13:14:56 +01:00
sinon . stub ( api , "getApiClient" ) . value ( ( ) => client ) ;
2022-11-14 19:48:27 +00:00
sinon . stub ( api , "getApiClientWithExternalAuth" ) . value ( ( ) => client ) ;
2020-07-07 18:32:29 +01:00
return spyGetContents ;
}
2020-08-07 17:15:46 +01:00
function mockListLanguages ( languages ) {
// Passing an auth token is required, so we just use a dummy value
2020-09-18 15:40:23 +01:00
const client = github . getOctokit ( "123" ) ;
2020-08-07 17:15:46 +01:00
const response = {
data : { } ,
} ;
for ( const language of languages ) {
response . data [ language ] = 123 ;
}
2023-01-18 20:22:33 +00:00
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
2023-07-13 11:17:33 +01:00
sinon . stub ( client . rest . repos , "listLanguages" ) . resolves ( response ) ;
2021-08-11 13:14:56 +01:00
sinon . stub ( api , "getApiClient" ) . value ( ( ) => client ) ;
2020-08-07 17:15:46 +01:00
}
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "load empty config" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript,python" ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( ) {
2020-06-26 15:33:59 +01:00
return {
2021-05-21 12:31:57 +02:00
byLanguage : {
javascript : { queries : [ "query1.ql" ] } ,
python : { queries : [ "query2.ql" ] } ,
} ,
2020-06-26 15:33:59 +01:00
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-06-26 15:33:59 +01:00
} ) ;
2023-04-18 05:46:51 +02:00
const config = await configUtils . initConfig ( languages , undefined , undefined , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , logger ) ;
t . deepEqual ( config , await configUtils . getDefaultConfig ( languages , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , logger ) ) ;
2020-05-05 17:32:58 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "loading config saves config" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( ) {
2020-06-26 15:33:59 +01:00
return {
2021-05-21 12:31:57 +02:00
byLanguage : {
javascript : { queries : [ "query1.ql" ] } ,
python : { queries : [ "query2.ql" ] } ,
} ,
2020-06-26 15:33:59 +01:00
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-06-26 15:33:59 +01:00
} ) ;
2020-05-05 17:32:58 +01:00
// Sanity check the saved config file does not already exist
2020-08-19 15:11:49 +01:00
t . false ( fs . existsSync ( configUtils . getPathToParsedConfigFile ( tmpDir ) ) ) ;
2020-08-28 17:28:05 +01:00
// Sanity check that getConfig returns undefined before we have called initConfig
t . deepEqual ( await configUtils . getConfig ( tmpDir , logger ) , undefined ) ;
2023-04-18 05:46:51 +02:00
const config1 = await configUtils . initConfig ( "javascript,python" , undefined , undefined , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , logger ) ;
2020-05-05 17:32:58 +01:00
// The saved config file should now exist
2020-08-19 15:11:49 +01:00
t . true ( fs . existsSync ( configUtils . getPathToParsedConfigFile ( tmpDir ) ) ) ;
2020-07-15 17:36:49 +01:00
// And that same newly-initialised config should now be returned by getConfig
2020-08-25 16:19:15 +01:00
const config2 = await configUtils . getConfig ( tmpDir , logger ) ;
2022-02-01 18:01:11 +00:00
t . not ( config2 , undefined ) ;
if ( config2 !== undefined ) {
2022-06-19 16:44:24 -07:00
// removes properties assigned to undefined.
const expectedConfig = JSON . parse ( JSON . stringify ( config1 ) ) ;
t . deepEqual ( expectedConfig , config2 ) ;
2022-02-01 18:01:11 +00:00
}
2020-05-05 17:32:58 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "load input outside of workspace" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-05-05 17:32:58 +01:00
try {
2023-04-18 05:46:51 +02:00
await configUtils . initConfig ( undefined , undefined , undefined , undefined , "../input" , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , ( 0 , codeql _1 . getCachedCodeQL ) ( ) , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-05-05 17:32:58 +01:00
}
catch ( err ) {
2023-07-11 11:05:40 +01:00
t . deepEqual ( err , new util _1 . UserError ( configUtils . getConfigFileOutsideWorkspaceErrorMessage ( path . join ( tmpDir , "../input" ) ) ) ) ;
2020-05-05 17:32:58 +01:00
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "load non-local input with invalid repo syntax" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-06-25 13:21:46 +01:00
// no filename given, just a repo
2020-09-14 10:44:43 +01:00
const configFile = "octo-org/codeql-config@main" ;
2020-06-25 13:21:46 +01:00
try {
2023-04-18 05:46:51 +02:00
await configUtils . initConfig ( undefined , undefined , undefined , undefined , configFile , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , ( 0 , codeql _1 . getCachedCodeQL ) ( ) , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-06-25 13:21:46 +01:00
}
catch ( err ) {
2023-07-11 11:05:40 +01:00
t . deepEqual ( err , new util _1 . UserError ( configUtils . getConfigFileRepoFormatInvalidMessage ( "octo-org/codeql-config@main" ) ) ) ;
2020-06-25 13:21:46 +01:00
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "load non-existent input" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
const configFile = "input" ;
2020-08-25 16:19:15 +01:00
t . false ( fs . existsSync ( path . join ( tmpDir , configFile ) ) ) ;
2020-05-05 17:32:58 +01:00
try {
2023-04-18 05:46:51 +02:00
await configUtils . initConfig ( languages , undefined , undefined , undefined , configFile , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , ( 0 , codeql _1 . getCachedCodeQL ) ( ) , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-05-05 17:32:58 +01:00
}
catch ( err ) {
2023-07-11 11:05:40 +01:00
t . deepEqual ( err , new util _1 . UserError ( configUtils . getConfigFileDoesNotExistErrorMessage ( path . join ( tmpDir , "input" ) ) ) ) ;
2020-05-05 17:32:58 +01:00
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "load non-empty input" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( ) {
2020-06-26 15:33:59 +01:00
return {
byLanguage : {
2020-09-14 10:44:43 +01:00
javascript : {
"/foo/a.ql" : { } ,
"/bar/b.ql" : { } ,
2020-06-26 15:33:59 +01:00
} ,
} ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-06-26 15:33:59 +01:00
} ) ;
2020-05-05 17:32:58 +01:00
// Just create a generic config object with non-default values for all fields
const inputFileContents = `
name: my config
disable-default-queries: true
queries:
- uses: ./foo
paths-ignore:
- a
- b
paths:
- c/d ` ;
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
2020-05-05 17:32:58 +01:00
// And the config we expect it to parse to
2020-06-26 15:33:59 +01:00
const expectedConfig = {
2020-08-17 13:34:55 +01:00
languages : [ languages _1 . Language . javascript ] ,
2020-09-18 09:52:44 +01:00
queries : {
javascript : {
2020-09-10 18:02:33 +01:00
builtin : [ ] ,
2021-04-01 12:38:13 +01:00
custom : [
{
queries : [ "/foo/a.ql" , "/bar/b.ql" ] ,
searchPath : tmpDir ,
} ,
] ,
2020-09-18 09:52:44 +01:00
} ,
} ,
2020-09-14 10:44:43 +01:00
pathsIgnore : [ "a" , "b" ] ,
paths : [ "c/d" ] ,
2020-07-20 16:33:37 +01:00
originalUserInput : {
2020-09-14 10:44:43 +01:00
name : "my config" ,
"disable-default-queries" : true ,
queries : [ { uses : "./foo" } ] ,
"paths-ignore" : [ "a" , "b" ] ,
paths : [ "c/d" ] ,
2020-07-20 16:33:37 +01:00
} ,
2020-08-19 15:11:49 +01:00
tempDir : tmpDir ,
2020-08-19 15:54:23 +01:00
codeQLCmd : codeQL . getPath ( ) ,
2020-11-30 16:33:38 +00:00
gitHubVersion ,
2021-05-17 10:35:09 +01:00
dbLocation : path . resolve ( tmpDir , "codeql_databases" ) ,
2021-06-03 09:32:44 -07:00
packs : { } ,
2021-10-28 14:15:22 +01:00
debugMode : false ,
2022-01-07 13:11:51 +00:00
debugArtifactName : "my-artifact" ,
debugDatabaseName : "my-db" ,
2022-08-10 15:42:45 -07:00
augmentationProperties : configUtils . defaultAugmentationProperties ,
2022-08-02 17:52:22 +01:00
trapCaches : { } ,
2022-08-15 14:44:43 +01:00
trapCacheDownloadTime : 0 ,
2020-06-26 15:33:59 +01:00
} ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
2020-09-08 10:14:51 +01:00
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
2023-04-18 05:46:51 +02:00
const actualConfig = await configUtils . initConfig ( languages , undefined , undefined , undefined , configFilePath , undefined , undefined , false , false , "my-artifact" , "my-db" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-05-05 17:32:58 +01:00
// Should exactly equal the object we constructed earlier
t . deepEqual ( actualConfig , expectedConfig ) ;
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Default queries are used" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-07-21 10:53:14 +01:00
// Check that the default behaviour is to add the default queries.
2020-07-21 12:19:37 +01:00
// In this case if a config file is specified but does not include
2020-07-21 10:53:14 +01:00
// the disable-default-queries field.
// We determine this by whether CodeQL.resolveQueries is called
// with the correct arguments.
const resolveQueriesArgs = [ ] ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-07-21 10:53:14 +01:00
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
return {
byLanguage : {
2020-09-14 10:44:43 +01:00
javascript : {
"foo.ql" : { } ,
2020-08-04 10:39:47 +01:00
} ,
2020-07-21 10:53:14 +01:00
} ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-07-21 10:53:14 +01:00
} ) ;
2020-07-21 12:46:19 +01:00
// The important point of this config is that it doesn't specify
2020-07-21 12:19:37 +01:00
// the disable-default-queries field.
2020-11-20 11:35:59 +01:00
// Any other details are hopefully irrelevant for this test.
2020-07-21 10:53:14 +01:00
const inputFileContents = `
paths:
- foo ` ;
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
const languages = "javascript" ;
2020-09-08 10:14:51 +01:00
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
2023-04-18 05:46:51 +02:00
await configUtils . initConfig ( languages , undefined , undefined , undefined , configFilePath , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-07-21 10:53:14 +01:00
// Check resolve queries was called correctly
t . deepEqual ( resolveQueriesArgs . length , 1 ) ;
2020-09-14 10:44:43 +01:00
t . deepEqual ( resolveQueriesArgs [ 0 ] . queries , [
"javascript-code-scanning.qls" ,
] ) ;
2020-07-21 10:53:14 +01:00
t . deepEqual ( resolveQueriesArgs [ 0 ] . extraSearchPath , undefined ) ;
} ) ;
} ) ;
2020-08-28 17:12:54 +01:00
/**
* Returns the provided queries, just in the right format for a resolved query
* This way we can test by seeing which returned items are in the final
* configuration.
*/
function queriesToResolvedQueryForm ( queries ) {
const dummyResolvedQueries = { } ;
2020-09-20 17:03:01 +08:00
for ( const q of queries ) {
2020-09-14 10:44:43 +01:00
dummyResolvedQueries [ q ] = { } ;
2020-09-20 17:03:01 +08:00
}
2020-08-28 17:12:54 +01:00
return {
byLanguage : {
2020-09-14 10:44:43 +01:00
javascript : dummyResolvedQueries ,
2020-08-28 17:12:54 +01:00
} ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
}
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Queries can be specified in config file" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-08-24 15:37:07 +01:00
const inputFileContents = `
name: my config
queries:
- uses: ./foo ` ;
2020-09-08 10:14:51 +01:00
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
2020-08-24 15:37:07 +01:00
const resolveQueriesArgs = [ ] ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-08-24 15:37:07 +01:00
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
2020-08-28 17:12:54 +01:00
return queriesToResolvedQueryForm ( queries ) ;
2020-08-24 15:37:07 +01:00
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-08-24 15:37:07 +01:00
} ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
2023-04-18 05:46:51 +02:00
const config = await configUtils . initConfig ( languages , undefined , undefined , undefined , configFilePath , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-08-24 15:37:07 +01:00
// Check resolveQueries was called correctly
// It'll be called once for the default queries
// and once for `./foo` from the config file.
t . deepEqual ( resolveQueriesArgs . length , 2 ) ;
t . deepEqual ( resolveQueriesArgs [ 1 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } foo ` ) ) ;
2020-08-24 15:37:07 +01:00
// Now check that the end result contains the default queries and the query from config
2020-09-18 09:52:44 +01:00
t . deepEqual ( config . queries [ "javascript" ] . builtin . length , 1 ) ;
t . deepEqual ( config . queries [ "javascript" ] . custom . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( config . queries [ "javascript" ] . builtin [ 0 ] . endsWith ( "javascript-code-scanning.qls" ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } foo ` ) ) ;
2020-08-24 15:37:07 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Queries from config file can be overridden in workflow file" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-07-27 11:03:57 +01:00
const inputFileContents = `
name: my config
queries:
- uses: ./foo ` ;
2020-09-08 10:14:51 +01:00
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
2020-08-24 14:33:02 +01:00
// This config item should take precedence over the config file but shouldn't affect the default queries.
2020-11-19 23:03:45 +01:00
const testQueries = "./override" ;
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
fs . mkdirSync ( path . join ( tmpDir , "override" ) ) ;
2020-07-27 11:03:57 +01:00
const resolveQueriesArgs = [ ] ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-07-27 11:03:57 +01:00
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
2020-08-28 17:12:54 +01:00
return queriesToResolvedQueryForm ( queries ) ;
2020-07-27 11:03:57 +01:00
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-07-27 11:03:57 +01:00
} ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
2023-04-18 05:46:51 +02:00
const config = await configUtils . initConfig ( languages , testQueries , undefined , undefined , configFilePath , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-07-27 11:03:57 +01:00
// Check resolveQueries was called correctly
2020-08-24 14:33:02 +01:00
// It'll be called once for the default queries and once for `./override`,
// but won't be called for './foo' from the config file.
t . deepEqual ( resolveQueriesArgs . length , 2 ) ;
t . deepEqual ( resolveQueriesArgs [ 1 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } override ` ) ) ;
2020-08-24 14:33:02 +01:00
// Now check that the end result contains only the default queries and the override query
2020-09-18 09:52:44 +01:00
t . deepEqual ( config . queries [ "javascript" ] . builtin . length , 1 ) ;
t . deepEqual ( config . queries [ "javascript" ] . custom . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( config . queries [ "javascript" ] . builtin [ 0 ] . endsWith ( "javascript-code-scanning.qls" ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } override ` ) ) ;
2020-07-27 11:03:57 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Queries in workflow file can be used in tandem with the 'disable default queries' option" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-09-14 10:44:43 +01:00
process . env [ "RUNNER_TEMP" ] = tmpDir ;
process . env [ "GITHUB_WORKSPACE" ] = tmpDir ;
2020-08-28 16:53:11 +01:00
const inputFileContents = `
name: my config
disable-default-queries: true ` ;
2020-09-08 10:14:51 +01:00
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
2020-11-19 23:03:45 +01:00
const testQueries = "./workflow-query" ;
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "workflow-query" ) ) ;
2020-08-28 16:53:11 +01:00
const resolveQueriesArgs = [ ] ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-08-28 16:53:11 +01:00
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
2020-08-28 17:12:54 +01:00
return queriesToResolvedQueryForm ( queries ) ;
2020-08-28 16:53:11 +01:00
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-08-28 16:53:11 +01:00
} ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
2023-04-18 05:46:51 +02:00
const config = await configUtils . initConfig ( languages , testQueries , undefined , undefined , configFilePath , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-08-28 16:53:11 +01:00
// Check resolveQueries was called correctly
// It'll be called once for `./workflow-query`,
// but won't be called for the default one since that was disabled
t . deepEqual ( resolveQueriesArgs . length , 1 ) ;
t . deepEqual ( resolveQueriesArgs [ 0 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } workflow-query ` ) ) ;
2020-08-28 16:53:11 +01:00
// Now check that the end result contains only the workflow query, and not the default one
2020-09-18 09:52:44 +01:00
t . deepEqual ( config . queries [ "javascript" ] . builtin . length , 0 ) ;
t . deepEqual ( config . queries [ "javascript" ] . custom . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( config . queries [ "javascript" ] . custom [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } workflow-query ` ) ) ;
2020-08-28 16:53:11 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Multiple queries can be specified in workflow file, no config file required" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "override1" ) ) ;
fs . mkdirSync ( path . join ( tmpDir , "override2" ) ) ;
2020-11-19 23:03:45 +01:00
const testQueries = "./override1,./override2" ;
2020-07-27 15:41:17 +01:00
const resolveQueriesArgs = [ ] ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-07-27 15:41:17 +01:00
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
2020-08-28 17:12:54 +01:00
return queriesToResolvedQueryForm ( queries ) ;
2020-07-27 15:41:17 +01:00
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-07-27 15:41:17 +01:00
} ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
2023-04-18 05:46:51 +02:00
const config = await configUtils . initConfig ( languages , testQueries , undefined , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-07-27 15:41:17 +01:00
// Check resolveQueries was called correctly:
// It'll be called once for the default queries,
2020-08-24 14:33:02 +01:00
// and then once for each of the two queries from the workflow
2020-07-27 15:41:17 +01:00
t . deepEqual ( resolveQueriesArgs . length , 3 ) ;
t . deepEqual ( resolveQueriesArgs [ 1 ] . queries . length , 1 ) ;
t . deepEqual ( resolveQueriesArgs [ 2 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } override1 ` ) ) ;
t . true ( resolveQueriesArgs [ 2 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } override2 ` ) ) ;
2020-08-24 14:33:02 +01:00
// Now check that the end result contains both the queries from the workflow, as well as the defaults
2020-09-18 09:52:44 +01:00
t . deepEqual ( config . queries [ "javascript" ] . builtin . length , 1 ) ;
t . deepEqual ( config . queries [ "javascript" ] . custom . length , 2 ) ;
2022-06-16 16:21:19 -07:00
t . true ( config . queries [ "javascript" ] . builtin [ 0 ] . endsWith ( "javascript-code-scanning.qls" ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } override1 ` ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } override2 ` ) ) ;
2020-07-27 15:41:17 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Queries in workflow file can be added to the set of queries without overriding config file" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-09-14 10:44:43 +01:00
process . env [ "RUNNER_TEMP" ] = tmpDir ;
process . env [ "GITHUB_WORKSPACE" ] = tmpDir ;
2020-08-27 17:11:56 +01:00
const inputFileContents = `
name: my config
queries:
- uses: ./foo ` ;
2020-09-08 10:14:51 +01:00
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
2020-08-27 17:11:56 +01:00
// These queries shouldn't override anything, because the value is prefixed with "+"
2020-11-19 23:03:45 +01:00
const testQueries = "+./additional1,./additional2" ;
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
fs . mkdirSync ( path . join ( tmpDir , "additional1" ) ) ;
fs . mkdirSync ( path . join ( tmpDir , "additional2" ) ) ;
2020-08-27 17:11:56 +01:00
const resolveQueriesArgs = [ ] ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( queries , extraSearchPath ) {
2020-08-27 17:11:56 +01:00
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
2020-08-28 17:12:54 +01:00
return queriesToResolvedQueryForm ( queries ) ;
2020-08-27 17:11:56 +01:00
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-08-27 17:11:56 +01:00
} ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
2023-04-18 05:46:51 +02:00
const config = await configUtils . initConfig ( languages , testQueries , undefined , undefined , configFilePath , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-08-27 17:11:56 +01:00
// Check resolveQueries was called correctly
// It'll be called once for the default queries,
// once for each of additional1 and additional2,
// and once for './foo' from the config file
t . deepEqual ( resolveQueriesArgs . length , 4 ) ;
t . deepEqual ( resolveQueriesArgs [ 1 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } additional1 ` ) ) ;
2020-08-27 17:11:56 +01:00
t . deepEqual ( resolveQueriesArgs [ 2 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 2 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } additional2 ` ) ) ;
2020-08-27 17:11:56 +01:00
t . deepEqual ( resolveQueriesArgs [ 3 ] . queries . length , 1 ) ;
2022-06-16 16:21:19 -07:00
t . true ( resolveQueriesArgs [ 3 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } foo ` ) ) ;
2020-08-27 17:11:56 +01:00
// Now check that the end result contains all the queries
2020-09-18 09:52:44 +01:00
t . deepEqual ( config . queries [ "javascript" ] . builtin . length , 1 ) ;
t . deepEqual ( config . queries [ "javascript" ] . custom . length , 3 ) ;
2022-06-16 16:21:19 -07:00
t . true ( config . queries [ "javascript" ] . builtin [ 0 ] . endsWith ( "javascript-code-scanning.qls" ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } additional1 ` ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } additional2 ` ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 2 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } foo ` ) ) ;
2020-08-27 17:11:56 +01:00
} ) ;
} ) ;
2023-04-18 05:43:21 +02:00
( 0 , ava _1 . default ) ( "Queries can be specified using config input" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2023-04-18 05:43:21 +02:00
const configInput = `
2023-03-18 06:37:28 +00:00
name: my config
queries:
- uses: ./foo
packs:
javascript:
- a/b@1.2.3
python:
- c/d@1.2.3
2023-03-18 15:14:34 +00:00
` ;
2023-03-18 06:37:28 +00:00
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
const resolveQueriesArgs = [ ] ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
async resolveQueries ( queries , extraSearchPath ) {
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
return queriesToResolvedQueryForm ( queries ) ;
} ,
async packDownload ( ) {
return { packs : [ ] } ;
} ,
} ) ;
// Only JS, python packs will be ignored
const languages = "javascript" ;
2023-04-18 05:46:51 +02:00
const config = await configUtils . initConfig ( languages , undefined , undefined , undefined , undefined , undefined , configInput , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2023-04-18 06:01:33 +02:00
// Check resolveQueries was called correctly
// It'll be called once for the default queries
// and once for `./foo` from the config file.
t . deepEqual ( resolveQueriesArgs . length , 2 ) ;
t . deepEqual ( resolveQueriesArgs [ 1 ] . queries . length , 1 ) ;
t . true ( resolveQueriesArgs [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } foo ` ) ) ;
t . deepEqual ( config . packs , {
[ languages _1 . Language . javascript ] : [ "a/b@1.2.3" ] ,
} ) ;
// Now check that the end result contains the default queries and the query from config
t . deepEqual ( config . queries [ "javascript" ] . builtin . length , 1 ) ;
t . deepEqual ( config . queries [ "javascript" ] . custom . length , 1 ) ;
t . true ( config . queries [ "javascript" ] . builtin [ 0 ] . endsWith ( "javascript-code-scanning.qls" ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } foo ` ) ) ;
} ) ;
} ) ;
( 0 , ava _1 . default ) ( "Using config input and file together, config input should be used." , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2023-04-18 06:01:33 +02:00
process . env [ "RUNNER_TEMP" ] = tmpDir ;
process . env [ "GITHUB_WORKSPACE" ] = tmpDir ;
const inputFileContents = `
name: my config
queries:
- uses: ./foo_file ` ;
const configFilePath = createConfigFile ( inputFileContents , tmpDir ) ;
const configInput = `
name: my config
queries:
- uses: ./foo
packs:
javascript:
- a/b@1.2.3
python:
- c/d@1.2.3
` ;
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
const resolveQueriesArgs = [ ] ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
async resolveQueries ( queries , extraSearchPath ) {
resolveQueriesArgs . push ( { queries , extraSearchPath } ) ;
return queriesToResolvedQueryForm ( queries ) ;
} ,
async packDownload ( ) {
return { packs : [ ] } ;
} ,
} ) ;
// Only JS, python packs will be ignored
const languages = "javascript" ;
const config = await configUtils . initConfig ( languages , undefined , undefined , undefined , undefined , configFilePath , configInput , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2023-03-18 06:37:28 +00:00
// Check resolveQueries was called correctly
// It'll be called once for the default queries
// and once for `./foo` from the config file.
t . deepEqual ( resolveQueriesArgs . length , 2 ) ;
t . deepEqual ( resolveQueriesArgs [ 1 ] . queries . length , 1 ) ;
t . true ( resolveQueriesArgs [ 1 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } foo ` ) ) ;
t . deepEqual ( config . packs , {
[ languages _1 . Language . javascript ] : [ "a/b@1.2.3" ] ,
} ) ;
// Now check that the end result contains the default queries and the query from config
t . deepEqual ( config . queries [ "javascript" ] . builtin . length , 1 ) ;
t . deepEqual ( config . queries [ "javascript" ] . custom . length , 1 ) ;
t . true ( config . queries [ "javascript" ] . builtin [ 0 ] . endsWith ( "javascript-code-scanning.qls" ) ) ;
t . true ( config . queries [ "javascript" ] . custom [ 0 ] . queries [ 0 ] . endsWith ( ` ${ path . sep } foo ` ) ) ;
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Invalid queries in workflow file handled correctly" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-09-14 10:44:43 +01:00
const queries = "foo/bar@v1@v3" ;
const languages = "javascript" ;
2020-08-24 16:44:59 +01:00
// This function just needs to be type-correct; it doesn't need to do anything,
// since we're deliberately passing in invalid data
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2021-01-15 18:40:06 +01:00
async resolveQueries ( ) {
2020-08-24 16:44:59 +01:00
return {
byLanguage : {
2020-09-14 10:44:43 +01:00
javascript : { } ,
2020-08-24 16:44:59 +01:00
} ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-08-24 16:44:59 +01:00
} ) ;
try {
2023-04-18 05:46:51 +02:00
await configUtils . initConfig ( languages , queries , undefined , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
t . fail ( "initConfig did not throw error" ) ;
2020-08-24 16:44:59 +01:00
}
catch ( err ) {
2023-07-11 11:05:40 +01:00
t . deepEqual ( err , new util _1 . UserError ( configUtils . getQueryUsesInvalid ( undefined , "foo/bar@v1@v3" ) ) ) ;
2020-08-24 16:44:59 +01:00
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "API client used when reading remote config" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( ) {
2020-06-26 15:33:59 +01:00
return {
2020-08-04 10:39:47 +01:00
byLanguage : {
2020-09-14 10:44:43 +01:00
javascript : {
"foo.ql" : { } ,
2020-08-04 10:39:47 +01:00
} ,
} ,
2020-06-26 15:33:59 +01:00
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-06-26 15:33:59 +01:00
} ) ;
2020-06-25 15:06:15 +01:00
const inputFileContents = `
name: my config
disable-default-queries: true
queries:
- uses: ./
2020-06-26 15:33:59 +01:00
- uses: ./foo
- uses: foo/bar@dev
2020-06-25 15:06:15 +01:00
paths-ignore:
- a
- b
paths:
- c/d ` ;
2020-06-26 13:51:14 +01:00
const dummyResponse = {
2020-07-07 18:32:29 +01:00
content : Buffer . from ( inputFileContents ) . toString ( "base64" ) ,
2020-06-26 13:51:14 +01:00
} ;
2020-07-07 18:32:29 +01:00
const spyGetContents = mockGetContents ( dummyResponse ) ;
2020-06-26 15:33:59 +01:00
// Create checkout directory for remote queries repository
2020-09-14 10:44:43 +01:00
fs . mkdirSync ( path . join ( tmpDir , "foo/bar/dev" ) , { recursive : true } ) ;
const configFile = "octo-org/codeql-config/config.yaml@main" ;
const languages = "javascript" ;
2023-04-18 05:46:51 +02:00
await configUtils . initConfig ( languages , undefined , undefined , undefined , configFile , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-06-26 09:32:44 +01:00
t . assert ( spyGetContents . called ) ;
2020-06-25 15:06:15 +01:00
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Remote config handles the case where a directory is provided" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-07-07 18:32:29 +01:00
const dummyResponse = [ ] ; // directories are returned as arrays
mockGetContents ( dummyResponse ) ;
2020-09-14 10:44:43 +01:00
const repoReference = "octo-org/codeql-config/config.yaml@main" ;
2020-06-26 15:56:33 +01:00
try {
2023-04-18 05:46:51 +02:00
await configUtils . initConfig ( undefined , undefined , undefined , undefined , repoReference , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , ( 0 , codeql _1 . getCachedCodeQL ) ( ) , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-06-26 15:56:33 +01:00
}
catch ( err ) {
2023-07-11 11:05:40 +01:00
t . deepEqual ( err , new util _1 . UserError ( configUtils . getConfigFileDirectoryGivenMessage ( repoReference ) ) ) ;
2020-06-26 15:56:33 +01:00
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Invalid format of remote config handled correctly" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-06-26 15:56:33 +01:00
const dummyResponse = {
2020-07-07 18:32:29 +01:00
// note no "content" property here
2020-06-26 15:56:33 +01:00
} ;
2020-07-07 18:32:29 +01:00
mockGetContents ( dummyResponse ) ;
2020-09-14 10:44:43 +01:00
const repoReference = "octo-org/codeql-config/config.yaml@main" ;
2020-06-26 15:56:33 +01:00
try {
2023-04-18 05:46:51 +02:00
await configUtils . initConfig ( undefined , undefined , undefined , undefined , repoReference , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , ( 0 , codeql _1 . getCachedCodeQL ) ( ) , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-06-26 15:56:33 +01:00
}
catch ( err ) {
2023-07-11 11:05:40 +01:00
t . deepEqual ( err , new util _1 . UserError ( configUtils . getConfigFileFormatInvalidMessage ( repoReference ) ) ) ;
2020-06-26 15:56:33 +01:00
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "No detected languages" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2020-08-07 17:15:46 +01:00
mockListLanguages ( [ ] ) ;
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2021-05-23 16:27:46 +02:00
async resolveLanguages ( ) {
return { } ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2021-05-23 16:27:46 +02:00
} ) ;
2020-08-06 17:45:42 +01:00
try {
2023-04-18 05:46:51 +02:00
await configUtils . initConfig ( undefined , undefined , undefined , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-08-06 17:45:42 +01:00
}
catch ( err ) {
2023-07-11 11:05:40 +01:00
t . deepEqual ( err , new util _1 . UserError ( configUtils . getNoLanguagesError ( ) ) ) ;
2020-08-06 17:45:42 +01:00
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Unknown languages" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2021-05-21 11:49:50 +02:00
const languages = "rubbish,english" ;
2020-08-06 17:45:42 +01:00
try {
2023-04-18 05:46:51 +02:00
await configUtils . initConfig ( languages , undefined , undefined , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , ( 0 , codeql _1 . getCachedCodeQL ) ( ) , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-08-06 17:45:42 +01:00
}
catch ( err ) {
2023-07-11 11:05:40 +01:00
t . deepEqual ( err , new util _1 . UserError ( configUtils . getUnknownLanguagesError ( [ "rubbish" , "english" ] ) ) ) ;
2020-08-06 17:45:42 +01:00
}
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Config specifies packages" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2021-06-03 09:32:44 -07:00
async resolveQueries ( ) {
return {
byLanguage : { } ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2021-06-03 09:32:44 -07:00
} ) ;
const inputFileContents = `
name: my config
disable-default-queries: true
packs:
- a/b@1.2.3
` ;
const configFile = path . join ( tmpDir , "codeql-config.yaml" ) ;
fs . writeFileSync ( configFile , inputFileContents ) ;
const languages = "javascript" ;
2023-04-18 05:46:51 +02:00
const { packs } = await configUtils . initConfig ( languages , undefined , undefined , undefined , configFile , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2021-06-03 09:32:44 -07:00
t . deepEqual ( packs , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . javascript ] : [ "a/b@1.2.3" ] ,
2021-06-03 09:32:44 -07:00
} ) ;
} ) ;
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "Config specifies packages for multiple languages" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2021-06-03 09:32:44 -07:00
async resolveQueries ( ) {
return {
byLanguage : {
cpp : { "/foo/a.ql" : { } } ,
} ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2021-06-03 09:32:44 -07:00
} ) ;
const inputFileContents = `
name: my config
disable-default-queries: true
queries:
- uses: ./foo
packs:
javascript:
- a/b@1.2.3
python:
- c/d@1.2.3
` ;
const configFile = path . join ( tmpDir , "codeql-config.yaml" ) ;
fs . writeFileSync ( configFile , inputFileContents ) ;
fs . mkdirSync ( path . join ( tmpDir , "foo" ) ) ;
const languages = "javascript,python,cpp" ;
2023-03-18 06:37:28 +00:00
const { packs , queries } = await configUtils . initConfig ( languages , undefined , undefined , undefined , configFile , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2021-06-03 09:32:44 -07:00
t . deepEqual ( packs , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . javascript ] : [ "a/b@1.2.3" ] ,
[ languages _1 . Language . python ] : [ "c/d@1.2.3" ] ,
2021-06-03 09:32:44 -07:00
} ) ;
t . deepEqual ( queries , {
cpp : {
builtin : [ ] ,
custom : [
{
queries : [ "/foo/a.ql" ] ,
searchPath : tmpDir ,
} ,
] ,
} ,
javascript : {
builtin : [ ] ,
custom : [ ] ,
} ,
python : {
builtin : [ ] ,
custom : [ ] ,
} ,
} ) ;
} ) ;
} ) ;
2020-05-26 19:23:28 +01:00
function doInvalidInputTest ( testName , inputFileContents , expectedErrorMessageGenerator ) {
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( ` load invalid input - ${ testName } ` , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2021-09-10 13:53:13 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
2020-09-14 10:44:43 +01:00
async resolveQueries ( ) {
2020-07-21 11:05:23 +01:00
return {
byLanguage : { } ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2020-07-21 11:05:23 +01:00
} ) ;
2020-09-14 10:44:43 +01:00
const languages = "javascript" ;
const configFile = "input" ;
2020-08-25 16:19:15 +01:00
const inputFile = path . join ( tmpDir , configFile ) ;
2020-09-14 10:44:43 +01:00
fs . writeFileSync ( inputFile , inputFileContents , "utf8" ) ;
2020-05-05 17:32:58 +01:00
try {
2023-04-18 05:46:51 +02:00
await configUtils . initConfig ( languages , undefined , undefined , undefined , configFile , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2020-09-14 10:44:43 +01:00
throw new Error ( "initConfig did not throw error" ) ;
2020-05-05 17:32:58 +01:00
}
catch ( err ) {
2023-07-11 11:05:40 +01:00
t . deepEqual ( err , new util _1 . UserError ( expectedErrorMessageGenerator ( inputFile ) ) ) ;
2020-05-05 17:32:58 +01:00
}
} ) ;
} ) ;
}
2020-09-14 10:44:43 +01:00
doInvalidInputTest ( "name invalid type" , `
2020-05-26 19:23:28 +01:00
name:
- foo: bar ` , configUtils . getNameInvalid ) ;
2020-09-14 10:44:43 +01:00
doInvalidInputTest ( "disable-default-queries invalid type" , ` disable-default-queries: 42 ` , configUtils . getDisableDefaultQueriesInvalid ) ;
doInvalidInputTest ( "queries invalid type" , ` queries: foo ` , configUtils . getQueriesInvalid ) ;
doInvalidInputTest ( "paths-ignore invalid type" , ` paths-ignore: bar ` , configUtils . getPathsIgnoreInvalid ) ;
doInvalidInputTest ( "paths invalid type" , ` paths: 17 ` , configUtils . getPathsInvalid ) ;
doInvalidInputTest ( "queries uses invalid type" , `
2020-05-26 19:23:28 +01:00
queries:
- uses:
2022-08-23 09:25:59 -07:00
- hello: world ` , configUtils . getQueriesMissingUses ) ;
2020-06-08 13:40:17 +01:00
function doInvalidQueryUsesTest ( input , expectedErrorMessageGenerator ) {
2020-05-26 19:23:28 +01:00
// Invalid contents of a "queries.uses" field.
// Should fail with the expected error message
const inputFileContents = `
name: my config
queries:
- name: foo
2020-09-14 10:44:43 +01:00
uses: ${ input } ` ;
doInvalidInputTest ( ` queries uses " ${ input } " ` , inputFileContents , expectedErrorMessageGenerator ) ;
2020-05-26 19:23:28 +01:00
}
// Various "uses" fields, and the errors they should produce
2020-09-14 10:44:43 +01:00
doInvalidQueryUsesTest ( "''" , ( c ) => configUtils . getQueryUsesInvalid ( c , undefined ) ) ;
doInvalidQueryUsesTest ( "foo/bar" , ( c ) => configUtils . getQueryUsesInvalid ( c , "foo/bar" ) ) ;
doInvalidQueryUsesTest ( "foo/bar@v1@v2" , ( c ) => configUtils . getQueryUsesInvalid ( c , "foo/bar@v1@v2" ) ) ;
doInvalidQueryUsesTest ( "foo@master" , ( c ) => configUtils . getQueryUsesInvalid ( c , "foo@master" ) ) ;
doInvalidQueryUsesTest ( "https://github.com/foo/bar@master" , ( c ) => configUtils . getQueryUsesInvalid ( c , "https://github.com/foo/bar@master" ) ) ;
doInvalidQueryUsesTest ( "./foo" , ( c ) => configUtils . getLocalPathDoesNotExist ( c , "foo" ) ) ;
doInvalidQueryUsesTest ( "./.." , ( c ) => configUtils . getLocalPathOutsideOfRepository ( c , ".." ) ) ;
2020-07-08 15:06:45 +01:00
const validPaths = [
2020-09-14 10:44:43 +01:00
"foo" ,
"foo/" ,
"foo/**" ,
"foo/**/" ,
"foo/**/**" ,
"foo/**/bar/**/baz" ,
"**/" ,
"**/foo" ,
"/foo" ,
2020-07-08 15:06:45 +01:00
] ;
2020-09-14 10:44:43 +01:00
const invalidPaths = [ "a/***/b" , "a/**b" , "a/b**" , "**" ] ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "path validations" , ( t ) => {
2020-07-08 15:06:45 +01:00
// Dummy values to pass to validateAndSanitisePath
2020-09-14 10:44:43 +01:00
const propertyName = "paths" ;
const configFile = "./.github/codeql/config.yml" ;
2020-11-19 23:03:45 +01:00
for ( const validPath of validPaths ) {
2021-09-10 13:53:13 -07:00
t . truthy ( configUtils . validateAndSanitisePath ( validPath , propertyName , configFile , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ) ;
2020-07-08 15:06:45 +01:00
}
2020-11-19 23:03:45 +01:00
for ( const invalidPath of invalidPaths ) {
2021-09-10 13:53:13 -07:00
t . throws ( ( ) => configUtils . validateAndSanitisePath ( invalidPath , propertyName , configFile , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ) ;
2020-07-08 15:06:45 +01:00
}
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "path sanitisation" , ( t ) => {
2020-07-08 15:06:45 +01:00
// Dummy values to pass to validateAndSanitisePath
2020-09-14 10:44:43 +01:00
const propertyName = "paths" ;
const configFile = "./.github/codeql/config.yml" ;
2020-07-08 15:06:45 +01:00
// Valid paths are not modified
2021-09-10 13:53:13 -07:00
t . deepEqual ( configUtils . validateAndSanitisePath ( "foo/bar" , propertyName , configFile , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) , "foo/bar" ) ;
2020-07-08 15:06:45 +01:00
// Trailing stars are stripped
2021-09-10 13:53:13 -07:00
t . deepEqual ( configUtils . validateAndSanitisePath ( "foo/**" , propertyName , configFile , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) , "foo/" ) ;
2020-07-08 15:06:45 +01:00
} ) ;
2021-06-03 09:32:44 -07:00
/**
* Test macro for ensuring the packs block is valid
*/
2022-02-01 18:01:11 +00:00
const parsePacksMacro = ava _1 . default . macro ( {
2022-06-22 13:06:19 -07:00
exec : ( t , packsByLanguage , languages , expected ) => t . deepEqual ( configUtils . parsePacksFromConfig ( packsByLanguage , languages , "/a/b" , mockLogger ) , expected ) ,
2022-02-01 18:01:11 +00:00
title : ( providedTitle = "" ) => ` Parse Packs: ${ providedTitle } ` ,
} ) ;
2021-06-03 09:32:44 -07:00
/**
* Test macro for testing when the packs block is invalid
*/
2022-02-01 18:01:11 +00:00
const parsePacksErrorMacro = ava _1 . default . macro ( {
2022-06-22 13:06:19 -07:00
exec : ( t , packsByLanguage , languages , expected ) => t . throws ( ( ) => configUtils . parsePacksFromConfig ( packsByLanguage , languages , "/a/b" , { } ) , {
2021-06-03 09:32:44 -07:00
message : expected ,
2022-02-01 18:01:11 +00:00
} ) ,
title : ( providedTitle = "" ) => ` Parse Packs Error: ${ providedTitle } ` ,
} ) ;
2021-06-23 15:41:52 -07:00
/**
* Test macro for testing when the packs block is invalid
*/
2022-02-01 18:01:11 +00:00
const invalidPackNameMacro = ava _1 . default . macro ( {
exec : ( t , name ) => parsePacksErrorMacro . exec ( t , { [ languages _1 . Language . cpp ] : [ name ] } , [ languages _1 . Language . cpp ] , new RegExp ( ` The configuration file "/a/b" is invalid: property "packs" " ${ name } " is not a valid pack ` ) ) ,
title : ( _providedTitle , arg ) => ` Invalid pack string: ${ arg } ` ,
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "no packs" , parsePacksMacro , { } , [ ] , { } ) ;
( 0 , ava _1 . default ) ( "two packs" , parsePacksMacro , [ "a/b" , "c/d@1.2.3" ] , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
2021-06-03 09:32:44 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "two packs with spaces" , parsePacksMacro , [ " a/b " , " c/d@1.2.3 " ] , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "two packs with language" , parsePacksMacro , {
2021-06-03 09:32:44 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
[ languages _1 . Language . java ] : [ "d/e" , "f/g@1.2.3" ] ,
} , [ languages _1 . Language . cpp , languages _1 . Language . java , languages _1 . Language . csharp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
[ languages _1 . Language . java ] : [ "d/e" , "f/g@1.2.3" ] ,
} ) ;
2022-06-22 13:06:19 -07:00
( 0 , ava _1 . default ) ( "two packs with unused language in config" , parsePacksMacro , {
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
[ languages _1 . Language . java ] : [ "d/e" , "f/g@1.2.3" ] ,
} , [ languages _1 . Language . cpp , languages _1 . Language . csharp ] , {
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
} ) ;
2022-04-26 19:47:59 -07:00
( 0 , ava _1 . default ) ( "packs with other valid names" , parsePacksMacro , [
// ranges are ok
"c/d@1.0" ,
"c/d@~1.0.0" ,
"c/d@~1.0.0:a/b" ,
"c/d@~1.0.0+abc:a/b" ,
"c/d@~1.0.0-abc:a/b" ,
"c/d:a/b" ,
// whitespace is removed
" c/d @ ~1.0.0 : b.qls " ,
// and it is retained within a path
" c/d @ ~1.0.0 : b/a path with/spaces.qls " ,
// this is valid. the path is '@'. It will probably fail when passed to the CLI
"c/d@1.2.3:@" ,
// this is valid, too. It will fail if it doesn't match a path
// (globbing is not done)
"c/d@1.2.3:+*)_(" ,
] , [ languages _1 . Language . cpp ] , {
2021-06-03 09:32:44 -07:00
[ languages _1 . Language . cpp ] : [
2022-04-26 19:47:59 -07:00
"c/d@1.0" ,
"c/d@~1.0.0" ,
"c/d@~1.0.0:a/b" ,
"c/d@~1.0.0+abc:a/b" ,
"c/d@~1.0.0-abc:a/b" ,
"c/d:a/b" ,
"c/d@~1.0.0:b.qls" ,
"c/d@~1.0.0:b/a path with/spaces.qls" ,
"c/d@1.2.3:@" ,
"c/d@1.2.3:+*)_(" ,
2021-06-03 09:32:44 -07:00
] ,
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "no language" , parsePacksErrorMacro , [ "a/b@1.2.3" ] , [ languages _1 . Language . java , languages _1 . Language . python ] , /The configuration file "\/a\/b" is invalid: property "packs" must split packages by language/ ) ;
( 0 , ava _1 . default ) ( "not an array" , parsePacksErrorMacro , { [ languages _1 . Language . cpp ] : "c/d" } , [ languages _1 . Language . cpp ] , /The configuration file "\/a\/b" is invalid: property "packs" must be an array of non-empty strings/ ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c" ) ; // all packs require at least a scope and a name
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c-/d" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "-c/d" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d_d" ) ;
2022-04-26 19:47:59 -07:00
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d@@" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d@1.0.0:" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d:" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d:/a" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "@1.0.0:a" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d@../a" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d@b/../a" ) ;
( 0 , ava _1 . default ) ( invalidPackNameMacro , "c/d:z@1" ) ;
2022-06-27 13:13:55 -07:00
/**
* Test macro for pretty printing pack specs
*/
const packSpecPrettyPrintingMacro = ava _1 . default . macro ( {
exec : ( t , packStr , packObj ) => {
const parsed = configUtils . parsePacksSpecification ( packStr ) ;
t . deepEqual ( parsed , packObj , "parsed pack spec is correct" ) ;
2023-07-19 17:37:43 +01:00
const stringified = ( 0 , util _1 . prettyPrintPack ) ( packObj ) ;
2022-06-27 13:13:55 -07:00
t . deepEqual ( stringified , packStr . trim ( ) , "pretty-printed pack spec is correct" ) ;
t . deepEqual ( configUtils . validatePackSpecification ( packStr ) , packStr . trim ( ) , "pack spec is valid" ) ;
} ,
title : ( _providedTitle , packStr ,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_packObj ) => ` Prettyprint pack spec: ' ${ packStr } ' ` ,
} ) ;
( 0 , ava _1 . default ) ( packSpecPrettyPrintingMacro , "a/b" , {
name : "a/b" ,
version : undefined ,
path : undefined ,
} ) ;
( 0 , ava _1 . default ) ( packSpecPrettyPrintingMacro , "a/b@~1.2.3" , {
name : "a/b" ,
version : "~1.2.3" ,
path : undefined ,
} ) ;
( 0 , ava _1 . default ) ( packSpecPrettyPrintingMacro , "a/b@~1.2.3:abc/def" , {
name : "a/b" ,
version : "~1.2.3" ,
path : "abc/def" ,
} ) ;
( 0 , ava _1 . default ) ( packSpecPrettyPrintingMacro , "a/b:abc/def" , {
name : "a/b" ,
version : undefined ,
path : "abc/def" ,
} ) ;
( 0 , ava _1 . default ) ( packSpecPrettyPrintingMacro , " a/b:abc/def " , {
name : "a/b" ,
version : undefined ,
path : "abc/def" ,
} ) ;
2021-06-23 15:41:52 -07:00
/**
* Test macro for testing the packs block and the packs input
*/
function parseInputAndConfigMacro ( t , packsFromConfig , packsFromInput , languages , expected ) {
2023-01-18 20:00:33 +00:00
t . deepEqual ( configUtils . parsePacks ( packsFromConfig , packsFromInput , ! ! packsFromInput ? . trim ( ) . startsWith ( "+" ) , // coerce to boolean
2022-08-11 09:56:08 -07:00
languages , "/a/b" , mockLogger ) , expected ) ;
2021-06-23 15:41:52 -07:00
}
parseInputAndConfigMacro . title = ( providedTitle ) => ` Parse Packs input and config: ${ providedTitle } ` ;
2022-11-24 11:06:29 -08:00
const mockLogger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
2022-06-19 16:44:24 -07:00
function parseInputAndConfigErrorMacro ( t , packsFromConfig , packsFromInput , languages , packsFromInputOverride , expected ) {
2021-06-23 15:41:52 -07:00
t . throws ( ( ) => {
2022-06-19 16:44:24 -07:00
configUtils . parsePacks ( packsFromConfig , packsFromInput , packsFromInputOverride , languages , "/a/b" , mockLogger ) ;
2021-06-23 15:41:52 -07:00
} , {
message : expected ,
} ) ;
}
parseInputAndConfigErrorMacro . title = ( providedTitle ) => ` Parse Packs input and config Error: ${ providedTitle } ` ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "input only" , parseInputAndConfigMacro , { } , " c/d " , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "c/d" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "input only with multiple" , parseInputAndConfigMacro , { } , "a/b , c/d@1.2.3" , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "input only with +" , parseInputAndConfigMacro , { } , " + a/b , c/d@1.2.3 " , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d@1.2.3" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "config only" , parseInputAndConfigMacro , [ "a/b" , "c/d" ] , " " , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "a/b" , "c/d" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "input overrides" , parseInputAndConfigMacro , [ "a/b" , "c/d" ] , " e/f, g/h@1.2.3 " , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "e/f" , "g/h@1.2.3" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2021-09-10 13:53:13 -07:00
( 0 , ava _1 . default ) ( "input and config" , parseInputAndConfigMacro , [ "a/b" , "c/d" ] , " +e/f, g/h@1.2.3 " , [ languages _1 . Language . cpp ] , {
2022-04-26 19:47:59 -07:00
[ languages _1 . Language . cpp ] : [ "e/f" , "g/h@1.2.3" , "a/b" , "c/d" ] ,
2021-06-23 15:41:52 -07:00
} ) ;
2022-06-19 16:44:24 -07:00
( 0 , ava _1 . default ) ( "input with no language" , parseInputAndConfigErrorMacro , { } , "c/d" , [ ] , false , /No languages specified/ ) ;
( 0 , ava _1 . default ) ( "input with two languages" , parseInputAndConfigErrorMacro , { } , "c/d" , [ languages _1 . Language . cpp , languages _1 . Language . csharp ] , false , /multi-language analysis/ ) ;
( 0 , ava _1 . default ) ( "input with + only" , parseInputAndConfigErrorMacro , { } , " + " , [ languages _1 . Language . cpp ] , true , /remove the '\+'/ ) ;
( 0 , ava _1 . default ) ( "input with invalid pack name" , parseInputAndConfigErrorMacro , { } , " xxx" , [ languages _1 . Language . cpp ] , false , /"xxx" is not a valid pack/ ) ;
2022-02-01 18:01:11 +00:00
const mlPoweredQueriesMacro = ava _1 . default . macro ( {
2022-10-11 18:56:15 +01:00
exec : async ( t , codeQLVersion , isMlPoweredQueriesEnabled , packsInput , queriesInput , expectedVersionString ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2022-02-01 18:01:11 +00:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
async getVersion ( ) {
return codeQLVersion ;
} ,
async resolveQueries ( ) {
return {
byLanguage : {
javascript : { "fake-query.ql" : { } } ,
} ,
noDeclaredLanguage : { } ,
multipleDeclaredLanguages : { } ,
} ;
} ,
2022-08-26 13:48:08 -07:00
async packDownload ( ) {
return { packs : [ ] } ;
} ,
2021-12-16 17:12:25 +00:00
} ) ;
2023-04-18 05:46:51 +02:00
const { packs } = await configUtils . initConfig ( "javascript" , queriesInput , packsInput , undefined , undefined , undefined , undefined , false , false , "" , "" , { owner : "github" , repo : "example" } , tmpDir , codeQL , tmpDir , gitHubVersion , sampleApiDetails , ( 0 , testing _utils _1 . createFeatures ) ( isMlPoweredQueriesEnabled ? [ feature _flags _1 . Feature . MlPoweredQueriesEnabled ] : [ ] ) , ( 0 , logging _1 . getRunnerLogger ) ( true ) ) ;
2022-02-04 16:28:09 +00:00
if ( expectedVersionString !== undefined ) {
2022-02-01 18:01:11 +00:00
t . deepEqual ( packs , {
[ languages _1 . Language . javascript ] : [
2022-04-26 19:47:59 -07:00
` codeql/javascript-experimental-atm-queries@ ${ expectedVersionString } ` ,
2022-02-01 18:01:11 +00:00
] ,
} ) ;
}
else {
t . deepEqual ( packs , { } ) ;
}
} ) ;
} ,
2022-10-11 18:56:15 +01:00
title : ( _providedTitle , codeQLVersion , isMlPoweredQueriesEnabled , packsInput , queriesInput , expectedVersionString ) => ` ML-powered queries ${ expectedVersionString !== undefined
2022-02-04 16:28:09 +00:00
? ` ${ expectedVersionString } are `
2022-10-11 18:56:15 +01:00
: "aren't" } loaded for packs: ${ packsInput } , queries: ${ queriesInput } using CLI v ${ codeQLVersion } when feature is ${ isMlPoweredQueriesEnabled ? "enabled" : "disabled" } ` ,
2022-02-04 16:28:09 +00:00
} ) ;
2022-10-11 18:56:15 +01:00
// macro, codeQLVersion, isMlPoweredQueriesEnabled, packsInput, queriesInput, expectedVersionString
// Test that ML-powered queries aren't run when the feature is off.
2023-06-12 11:34:01 +01:00
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.12.3" , false , undefined , "security-extended" , undefined ) ;
2022-03-30 18:17:06 +01:00
// Test that ML-powered queries aren't run when the user hasn't specified that we should run the
2023-02-06 11:26:03 -08:00
// `security-extended`, `security-and-quality`, or `security-experimental` query suite.
2023-06-12 11:34:01 +01:00
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.12.3" , true , undefined , undefined , undefined ) ;
2022-03-30 18:17:06 +01:00
// Test that we don't inject an ML-powered query pack if the user has already specified one.
2023-06-12 11:34:01 +01:00
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.12.3" , true , "codeql/javascript-experimental-atm-queries@0.0.1" , "security-and-quality" , "0.0.1" ) ;
// Test that ML-powered queries ~0.3.0 are run on all platforms running `security-extended` on
// CodeQL CLI 2.9.4+.
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.9.4" , true , undefined , "security-extended" , "~0.3.0" ) ;
// Test that ML-powered queries ~0.3.0 are run on all platforms running `security-and-quality` on
// CodeQL CLI 2.9.4+.
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.9.4" , true , undefined , "security-and-quality" , "~0.3.0" ) ;
// Test that ML-powered queries ~0.4.0 are run on all platforms running `security-extended` on
// CodeQL CLI 2.11.3+.
2022-11-08 13:24:32 +01:00
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.11.3" , true , undefined , "security-extended" , "~0.4.0" ) ;
2023-06-12 11:34:01 +01:00
// Test that ML-powered queries ~0.4.0 are run on all platforms running `security-and-quality` on
// CodeQL CLI 2.11.3+.
2022-11-08 13:24:32 +01:00
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.11.3" , true , undefined , "security-and-quality" , "~0.4.0" ) ;
2023-02-06 11:26:03 -08:00
// Test that ML-powered queries are run on all platforms running `security-experimental` on CodeQL
// CLI 2.12.1+.
( 0 , ava _1 . default ) ( mlPoweredQueriesMacro , "2.12.1" , true , undefined , "security-experimental" , "~0.4.0" ) ;
2022-06-19 16:44:24 -07:00
const calculateAugmentationMacro = ava _1 . default . macro ( {
exec : async ( t , _title , rawPacksInput , rawQueriesInput , languages , expectedAugmentationProperties ) => {
const actualAugmentationProperties = configUtils . calculateAugmentation ( rawPacksInput , rawQueriesInput , languages ) ;
t . deepEqual ( actualAugmentationProperties , expectedAugmentationProperties ) ;
} ,
title : ( _ , title ) => ` Calculate Augmentation: ${ title } ` ,
} ) ;
( 0 , ava _1 . default ) ( calculateAugmentationMacro , "All empty" , undefined , undefined , [ languages _1 . Language . javascript ] , {
queriesInputCombines : false ,
queriesInput : undefined ,
packsInputCombines : false ,
packsInput : undefined ,
injectedMlQueries : false ,
} ) ;
( 0 , ava _1 . default ) ( calculateAugmentationMacro , "With queries" , undefined , " a, b , c, d" , [ languages _1 . Language . javascript ] , {
queriesInputCombines : false ,
queriesInput : [ { uses : "a" } , { uses : "b" } , { uses : "c" } , { uses : "d" } ] ,
packsInputCombines : false ,
packsInput : undefined ,
injectedMlQueries : false ,
} ) ;
( 0 , ava _1 . default ) ( calculateAugmentationMacro , "With queries combining" , undefined , " + a, b , c, d " , [ languages _1 . Language . javascript ] , {
queriesInputCombines : true ,
queriesInput : [ { uses : "a" } , { uses : "b" } , { uses : "c" } , { uses : "d" } ] ,
packsInputCombines : false ,
packsInput : undefined ,
injectedMlQueries : false ,
} ) ;
( 0 , ava _1 . default ) ( calculateAugmentationMacro , "With packs" , " codeql/a , codeql/b , codeql/c , codeql/d " , undefined , [ languages _1 . Language . javascript ] , {
queriesInputCombines : false ,
queriesInput : undefined ,
packsInputCombines : false ,
packsInput : [ "codeql/a" , "codeql/b" , "codeql/c" , "codeql/d" ] ,
injectedMlQueries : false ,
} ) ;
( 0 , ava _1 . default ) ( calculateAugmentationMacro , "With packs combining" , " + codeql/a, codeql/b, codeql/c, codeql/d" , undefined , [ languages _1 . Language . javascript ] , {
queriesInputCombines : false ,
queriesInput : undefined ,
packsInputCombines : true ,
packsInput : [ "codeql/a" , "codeql/b" , "codeql/c" , "codeql/d" ] ,
injectedMlQueries : false ,
} ) ;
const calculateAugmentationErrorMacro = ava _1 . default . macro ( {
exec : async ( t , _title , rawPacksInput , rawQueriesInput , languages , expectedError ) => {
t . throws ( ( ) => configUtils . calculateAugmentation ( rawPacksInput , rawQueriesInput , languages ) , { message : expectedError } ) ;
} ,
title : ( _ , title ) => ` Calculate Augmentation Error: ${ title } ` ,
} ) ;
( 0 , ava _1 . default ) ( calculateAugmentationErrorMacro , "Plus (+) with nothing else (queries)" , undefined , " + " , [ languages _1 . Language . javascript ] , /The workflow property "queries" is invalid/ ) ;
( 0 , ava _1 . default ) ( calculateAugmentationErrorMacro , "Plus (+) with nothing else (packs)" , " + " , undefined , [ languages _1 . Language . javascript ] , /The workflow property "packs" is invalid/ ) ;
( 0 , ava _1 . default ) ( calculateAugmentationErrorMacro , "Packs input with multiple languages" , " + a/b, c/d " , undefined , [ languages _1 . Language . javascript , languages _1 . Language . java ] , /Cannot specify a 'packs' input in a multi-language analysis/ ) ;
( 0 , ava _1 . default ) ( calculateAugmentationErrorMacro , "Packs input with no languages" , " + a/b, c/d " , undefined , [ ] , /No languages specified/ ) ;
( 0 , ava _1 . default ) ( calculateAugmentationErrorMacro , "Invalid packs" , " a-pack-without-a-scope " , undefined , [ languages _1 . Language . javascript ] , /"a-pack-without-a-scope" is not a valid pack/ ) ;
2022-08-29 12:57:46 -07:00
( 0 , ava _1 . default ) ( "downloadPacks-no-registries" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2022-08-29 12:57:46 -07:00
const packDownloadStub = sinon . stub ( ) ;
packDownloadStub . callsFake ( ( packs ) => ( {
packs ,
} ) ) ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
packDownload : packDownloadStub ,
} ) ;
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
// packs are supplied for go, java, and python
// analyzed languages are java, javascript, and python
await configUtils . downloadPacks ( codeQL , [ languages _1 . Language . javascript , languages _1 . Language . java , languages _1 . Language . python ] , {
java : [ "a" , "b" ] ,
go : [ "c" , "d" ] ,
python : [ "e" , "f" ] ,
2023-02-07 10:40:49 -08:00
} , sampleApiDetails , undefined , // registriesAuthTokens
2023-02-09 11:19:27 -08:00
tmpDir , logger ) ;
2022-09-06 10:41:32 -07:00
// Expecting packs to be downloaded once for java and once for python
2022-08-29 12:57:46 -07:00
t . deepEqual ( packDownloadStub . callCount , 2 ) ;
// no config file was created, so pass `undefined` as the config file path
t . deepEqual ( packDownloadStub . firstCall . args , [ [ "a" , "b" ] , undefined ] ) ;
t . deepEqual ( packDownloadStub . secondCall . args , [ [ "e" , "f" ] , undefined ] ) ;
} ) ;
} ) ;
( 0 , ava _1 . default ) ( "downloadPacks-with-registries" , async ( t ) => {
// same thing, but this time include a registries block and
// associated env vars
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2022-08-29 12:57:46 -07:00
process . env . GITHUB _TOKEN = "not-a-token" ;
2023-02-09 12:58:15 -08:00
process . env . CODEQL _REGISTRIES _AUTH = undefined ;
2022-08-29 12:57:46 -07:00
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
2023-02-07 10:40:49 -08:00
const registriesInput = yaml . dump ( [
2022-08-29 12:57:46 -07:00
{
2022-09-07 20:32:47 -07:00
// no slash
2022-08-29 12:57:46 -07:00
url : "http://ghcr.io" ,
2023-04-04 12:21:07 -07:00
packages : [ "codeql/*" , "codeql-testing/*" ] ,
2022-09-01 16:07:26 -07:00
token : "not-a-token" ,
2022-08-29 12:57:46 -07:00
} ,
{
2022-09-07 20:32:47 -07:00
// with slash
2022-08-29 12:57:46 -07:00
url : "https://containers.GHEHOSTNAME1/v2/" ,
packages : "semmle/*" ,
2022-09-06 10:41:32 -07:00
token : "still-not-a-token" ,
2022-08-29 12:57:46 -07:00
} ,
2023-02-07 10:40:49 -08:00
] ) ;
2022-09-07 20:32:47 -07:00
// append a slash to the first url
2023-02-07 10:40:49 -08:00
const registries = yaml . load ( registriesInput ) ;
2022-09-07 20:32:47 -07:00
const expectedRegistries = registries . map ( ( r , i ) => ( {
packages : r . packages ,
url : i === 0 ? ` ${ r . url } / ` : r . url ,
} ) ) ;
2022-08-29 12:57:46 -07:00
const expectedConfigFile = path . join ( tmpDir , "qlconfig.yml" ) ;
const packDownloadStub = sinon . stub ( ) ;
packDownloadStub . callsFake ( ( packs , configFile ) => {
t . deepEqual ( configFile , expectedConfigFile ) ;
// verify the env vars were set correctly
2022-09-06 10:41:32 -07:00
t . deepEqual ( process . env . GITHUB _TOKEN , sampleApiDetails . auth ) ;
2022-09-06 10:45:02 -07:00
t . deepEqual ( process . env . CODEQL _REGISTRIES _AUTH , "http://ghcr.io=not-a-token,https://containers.GHEHOSTNAME1/v2/=still-not-a-token" ) ;
2022-08-29 12:57:46 -07:00
// verify the config file contents were set correctly
const config = yaml . load ( fs . readFileSync ( configFile , "utf8" ) ) ;
2022-09-07 20:32:47 -07:00
t . deepEqual ( config . registries , expectedRegistries ) ;
2022-08-29 12:57:46 -07:00
return {
packs ,
} ;
} ) ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
packDownload : packDownloadStub ,
2022-09-07 15:26:30 -07:00
getVersion : ( ) => Promise . resolve ( "2.10.5" ) ,
2022-08-29 12:57:46 -07:00
} ) ;
// packs are supplied for go, java, and python
// analyzed languages are java, javascript, and python
await configUtils . downloadPacks ( codeQL , [ languages _1 . Language . javascript , languages _1 . Language . java , languages _1 . Language . python ] , {
java : [ "a" , "b" ] ,
go : [ "c" , "d" ] ,
python : [ "e" , "f" ] ,
2023-02-07 10:40:49 -08:00
} , sampleApiDetails , registriesInput , tmpDir , logger ) ;
2022-08-29 12:57:46 -07:00
// Same packs are downloaded as in previous test
t . deepEqual ( packDownloadStub . callCount , 2 ) ;
t . deepEqual ( packDownloadStub . firstCall . args , [
[ "a" , "b" ] ,
expectedConfigFile ,
] ) ;
t . deepEqual ( packDownloadStub . secondCall . args , [
[ "e" , "f" ] ,
expectedConfigFile ,
] ) ;
// Verify that the env vars were unset.
t . deepEqual ( process . env . GITHUB _TOKEN , "not-a-token" ) ;
2023-02-09 12:58:15 -08:00
t . deepEqual ( process . env . CODEQL _REGISTRIES _AUTH , undefined ) ;
2022-08-26 13:48:08 -07:00
} ) ;
} ) ;
2022-09-07 15:26:30 -07:00
( 0 , ava _1 . default ) ( "downloadPacks-with-registries fails on 2.10.3" , async ( t ) => {
// same thing, but this time include a registries block and
// associated env vars
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2022-09-07 15:26:30 -07:00
process . env . GITHUB _TOKEN = "not-a-token" ;
process . env . CODEQL _REGISTRIES _AUTH = "not-a-registries-auth" ;
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
2023-02-07 10:40:49 -08:00
const registriesInput = yaml . dump ( [
2022-09-07 15:26:30 -07:00
{
url : "http://ghcr.io" ,
2023-04-04 12:21:07 -07:00
packages : [ "codeql/*" , "codeql-testing/*" ] ,
2022-09-07 15:26:30 -07:00
token : "not-a-token" ,
} ,
{
url : "https://containers.GHEHOSTNAME1/v2/" ,
packages : "semmle/*" ,
token : "still-not-a-token" ,
} ,
2023-02-07 10:40:49 -08:00
] ) ;
2022-09-07 15:26:30 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
getVersion : ( ) => Promise . resolve ( "2.10.3" ) ,
} ) ;
await t . throwsAsync ( async ( ) => {
2023-02-07 10:40:49 -08:00
return await configUtils . downloadPacks ( codeQL , [ languages _1 . Language . javascript , languages _1 . Language . java , languages _1 . Language . python ] , { } , sampleApiDetails , registriesInput , tmpDir , logger ) ;
2022-09-07 20:32:47 -07:00
} , { instanceOf : Error } , "'registries' input is not supported on CodeQL versions less than 2.10.4." ) ;
} ) ;
} ) ;
( 0 , ava _1 . default ) ( "downloadPacks-with-registries fails with invalid registries block" , async ( t ) => {
// same thing, but this time include a registries block and
// associated env vars
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2022-09-07 20:32:47 -07:00
process . env . GITHUB _TOKEN = "not-a-token" ;
process . env . CODEQL _REGISTRIES _AUTH = "not-a-registries-auth" ;
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
2023-02-07 10:40:49 -08:00
const registriesInput = yaml . dump ( [
2022-09-07 20:32:47 -07:00
{
// missing url property
2023-04-04 12:21:07 -07:00
packages : [ "codeql/*" , "codeql-testing/*" ] ,
2022-09-07 20:32:47 -07:00
token : "not-a-token" ,
} ,
{
url : "https://containers.GHEHOSTNAME1/v2/" ,
packages : "semmle/*" ,
token : "still-not-a-token" ,
} ,
2023-02-07 10:40:49 -08:00
] ) ;
2022-09-07 20:32:47 -07:00
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
getVersion : ( ) => Promise . resolve ( "2.10.4" ) ,
} ) ;
await t . throwsAsync ( async ( ) => {
2023-02-07 10:40:49 -08:00
return await configUtils . downloadPacks ( codeQL , [ languages _1 . Language . javascript , languages _1 . Language . java , languages _1 . Language . python ] , { } , sampleApiDetails , registriesInput , tmpDir , logger ) ;
2022-09-07 20:32:47 -07:00
} , { instanceOf : Error } , "Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties." ) ;
2022-09-07 15:26:30 -07:00
} ) ;
} ) ;
2023-02-07 10:40:49 -08:00
// the happy path for generateRegistries is already tested in downloadPacks.
// these following tests are for the error cases and when nothing is generated.
( 0 , ava _1 . default ) ( "no generateRegistries when CLI is too old" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2023-02-07 10:40:49 -08:00
const registriesInput = yaml . dump ( [
{
// no slash
url : "http://ghcr.io" ,
2023-04-04 12:21:07 -07:00
packages : [ "codeql/*" , "codeql-testing/*" ] ,
2023-02-07 10:40:49 -08:00
token : "not-a-token" ,
} ,
] ) ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
// Accepted CLI versions are 2.10.4 or higher
getVersion : ( ) => Promise . resolve ( "2.10.3" ) ,
} ) ;
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
await t . throwsAsync ( async ( ) => await configUtils . generateRegistries ( registriesInput , codeQL , tmpDir , logger ) , undefined , "'registries' input is not supported on CodeQL versions less than 2.10.4." ) ;
} ) ;
} ) ;
( 0 , ava _1 . default ) ( "no generateRegistries when registries is undefined" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2023-02-07 10:40:49 -08:00
const registriesInput = undefined ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
// Accepted CLI versions are 2.10.4 or higher
getVersion : ( ) => Promise . resolve ( codeql _1 . CODEQL _VERSION _GHES _PACK _DOWNLOAD ) ,
} ) ;
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
const { registriesAuthTokens , qlconfigFile } = await configUtils . generateRegistries ( registriesInput , codeQL , tmpDir , logger ) ;
t . is ( registriesAuthTokens , undefined ) ;
t . is ( qlconfigFile , undefined ) ;
} ) ;
} ) ;
2023-02-09 12:58:15 -08:00
( 0 , ava _1 . default ) ( "generateRegistries prefers original CODEQL_REGISTRIES_AUTH" , async ( t ) => {
2023-07-11 11:05:40 +01:00
return await ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
2023-02-09 12:58:15 -08:00
process . env . CODEQL _REGISTRIES _AUTH = "original" ;
const registriesInput = yaml . dump ( [
{
url : "http://ghcr.io" ,
2023-04-04 12:21:07 -07:00
packages : [ "codeql/*" , "codeql-testing/*" ] ,
2023-02-09 12:58:15 -08:00
token : "not-a-token" ,
} ,
] ) ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
// Accepted CLI versions are 2.10.4 or higher
getVersion : ( ) => Promise . resolve ( codeql _1 . CODEQL _VERSION _GHES _PACK _DOWNLOAD ) ,
} ) ;
const logger = ( 0 , logging _1 . getRunnerLogger ) ( true ) ;
const { registriesAuthTokens , qlconfigFile } = await configUtils . generateRegistries ( registriesInput , codeQL , tmpDir , logger ) ;
t . is ( registriesAuthTokens , "original" ) ;
t . is ( qlconfigFile , path . join ( tmpDir , "qlconfig.yml" ) ) ;
} ) ;
} ) ;
2022-11-23 16:16:02 -08:00
// getLanguages
const mockRepositoryNwo = ( 0 , repository _1 . parseRepositoryNwo ) ( "owner/repo" ) ;
// eslint-disable-next-line github/array-foreach
[
{
name : "languages from input" ,
codeqlResolvedLanguages : [ "javascript" , "java" , "python" ] ,
languagesInput : "jAvAscript, \n jaVa" ,
languagesInRepository : [ "SwiFt" , "other" ] ,
expectedLanguages : [ "javascript" , "java" ] ,
expectedApiCall : false ,
} ,
{
name : "languages from github api" ,
codeqlResolvedLanguages : [ "javascript" , "java" , "python" ] ,
languagesInput : "" ,
languagesInRepository : [ " jAvAscript\n \t" , " jaVa" , "SwiFt" , "other" ] ,
expectedLanguages : [ "javascript" , "java" ] ,
expectedApiCall : true ,
} ,
{
name : "aliases from input" ,
codeqlResolvedLanguages : [ "javascript" , "csharp" , "cpp" , "java" , "python" ] ,
languagesInput : " typEscript\n \t, C#, c , KoTlin" ,
languagesInRepository : [ "SwiFt" , "other" ] ,
expectedLanguages : [ "javascript" , "csharp" , "cpp" , "java" ] ,
expectedApiCall : false ,
} ,
{
name : "duplicate languages from input" ,
codeqlResolvedLanguages : [ "javascript" , "java" , "python" ] ,
languagesInput : "jAvAscript, \n jaVa, kotlin, typescript" ,
languagesInRepository : [ "SwiFt" , "other" ] ,
expectedLanguages : [ "javascript" , "java" ] ,
expectedApiCall : false ,
} ,
{
name : "aliases from github api" ,
codeqlResolvedLanguages : [ "javascript" , "csharp" , "cpp" , "java" , "python" ] ,
languagesInput : "" ,
languagesInRepository : [ " typEscript\n \t" , " C#" , "c" , "other" ] ,
expectedLanguages : [ "javascript" , "csharp" , "cpp" ] ,
expectedApiCall : true ,
} ,
{
name : "no languages" ,
codeqlResolvedLanguages : [ "javascript" , "java" , "python" ] ,
languagesInput : "" ,
languagesInRepository : [ ] ,
expectedApiCall : true ,
expectedError : configUtils . getNoLanguagesError ( ) ,
} ,
{
name : "unrecognized languages from input" ,
codeqlResolvedLanguages : [ "javascript" , "java" , "python" ] ,
languagesInput : "a, b, c, javascript" ,
languagesInRepository : [ ] ,
expectedApiCall : false ,
expectedError : configUtils . getUnknownLanguagesError ( [ "a" , "b" ] ) ,
} ,
] . forEach ( ( args ) => {
2022-11-24 11:06:29 -08:00
( 0 , ava _1 . default ) ( ` getLanguages: ${ args . name } ` , async ( t ) => {
2022-11-23 16:16:02 -08:00
const mockRequest = ( 0 , testing _utils _1 . mockLanguagesInRepo ) ( args . languagesInRepository ) ;
const languages = args . codeqlResolvedLanguages . reduce ( ( acc , lang ) => ( {
... acc ,
[ lang ] : true ,
} ) , { } ) ;
const codeQL = ( 0 , codeql _1 . setCodeQL ) ( {
resolveLanguages : ( ) => Promise . resolve ( languages ) ,
} ) ;
2022-11-24 11:06:29 -08:00
if ( args . expectedLanguages ) {
// happy path
const actualLanguages = await configUtils . getLanguages ( codeQL , args . languagesInput , mockRepositoryNwo , mockLogger ) ;
t . deepEqual ( actualLanguages . sort ( ) , args . expectedLanguages . sort ( ) ) ;
}
else {
// there is an error
await t . throwsAsync ( async ( ) => await configUtils . getLanguages ( codeQL , args . languagesInput , mockRepositoryNwo , mockLogger ) , { message : args . expectedError } ) ;
}
2022-11-23 16:16:02 -08:00
t . deepEqual ( mockRequest . called , args . expectedApiCall ) ;
} ) ;
} ) ;
2023-07-19 16:48:21 +01:00
const ML _POWERED _JS _STATUS _TESTS = [
// If no packs are loaded, status is false.
[ [ ] , "false" ] ,
// If another pack is loaded but not the ML-powered query pack, status is false.
[ [ "some-other/pack" ] , "false" ] ,
// If the ML-powered query pack is loaded with a specific version, status is that version.
2023-07-19 17:37:43 +01:00
[ [ ` ${ util _1 . ML _POWERED _JS _QUERIES _PACK _NAME } @~0.1.0 ` ] , "~0.1.0" ] ,
2023-07-19 16:48:21 +01:00
// If the ML-powered query pack is loaded with a specific version and another pack is loaded, the
// status is the version of the ML-powered query pack.
2023-07-19 17:37:43 +01:00
[ [ "some-other/pack" , ` ${ util _1 . ML _POWERED _JS _QUERIES _PACK _NAME } @~0.1.0 ` ] , "~0.1.0" ] ,
2023-07-19 16:48:21 +01:00
// If the ML-powered query pack is loaded without a version, the status is "latest".
2023-07-19 17:37:43 +01:00
[ [ util _1 . ML _POWERED _JS _QUERIES _PACK _NAME ] , "latest" ] ,
2023-07-19 16:48:21 +01:00
// If the ML-powered query pack is loaded with two different versions, the status is "other".
[
[
2023-07-19 17:37:43 +01:00
` ${ util _1 . ML _POWERED _JS _QUERIES _PACK _NAME } @~0.0.1 ` ,
` ${ util _1 . ML _POWERED _JS _QUERIES _PACK _NAME } @~0.0.2 ` ,
2023-07-19 16:48:21 +01:00
] ,
"other" ,
] ,
// If the ML-powered query pack is loaded with no specific version, and another pack is loaded,
// the status is "latest".
2023-07-19 17:37:43 +01:00
[ [ "some-other/pack" , util _1 . ML _POWERED _JS _QUERIES _PACK _NAME ] , "latest" ] ,
2023-07-19 16:48:21 +01:00
] ;
for ( const [ packs , expectedStatus ] of ML _POWERED _JS _STATUS _TESTS ) {
const packDescriptions = ` [ ${ packs
. map ( ( pack ) => JSON . stringify ( pack ) )
. join ( ", " ) } ] ` ;
( 0 , ava _1 . default ) ( ` ML-powered JS queries status report is " ${ expectedStatus } " for packs = ${ packDescriptions } ` , ( t ) => {
return ( 0 , util _1 . withTmpDir ) ( async ( tmpDir ) => {
const config = {
languages : [ ] ,
queries : { } ,
paths : [ ] ,
pathsIgnore : [ ] ,
originalUserInput : { } ,
tempDir : tmpDir ,
codeQLCmd : "" ,
gitHubVersion : {
type : util _1 . GitHubVariant . DOTCOM ,
} ,
dbLocation : "" ,
packs : {
javascript : packs ,
} ,
debugMode : false ,
debugArtifactName : util _1 . DEFAULT _DEBUG _ARTIFACT _NAME ,
debugDatabaseName : util _1 . DEFAULT _DEBUG _DATABASE _NAME ,
augmentationProperties : {
injectedMlQueries : false ,
packsInputCombines : false ,
queriesInputCombines : false ,
} ,
trapCaches : { } ,
trapCacheDownloadTime : 0 ,
} ;
t . is ( configUtils . getMlPoweredJsQueriesStatus ( config ) , expectedStatus ) ;
} ) ;
} ) ;
}
2020-05-05 17:32:58 +01:00
//# sourceMappingURL=config-utils.test.js.map