From 0383a91a68f9853d568865a15042593727201fa3 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Mon, 28 Mar 2022 11:47:51 -0700 Subject: [PATCH 1/4] Display proper download state in remote results view Before displaying any results for a remote query, ensure that all downloaded results are in memory. This ensures the proper download icon is displayed alongside each NWO. --- .../analyses-results-manager.ts | 40 +++++++++++++++++-- .../src/remote-queries/download-link.ts | 15 +++++++ .../remote-queries/gh-actions-api-client.ts | 6 +-- .../remote-queries-interface.ts | 12 ++++-- .../remote-queries/remote-queries-manager.ts | 2 +- .../src/remote-queries/sarif-processing.ts | 11 ++++- .../query-result.json | 11 +++++ .../no-workspace/download-link.test.ts | 31 ++++++++++++++ .../no-workspace/remote-query-history.test.ts | 36 +++++++++++++---- .../test/pure-tests/sarif-processing.test.ts | 4 +- 10 files changed, 146 insertions(+), 22 deletions(-) create mode 100644 extensions/ql-vscode/src/vscode-tests/no-workspace/download-link.test.ts diff --git a/extensions/ql-vscode/src/remote-queries/analyses-results-manager.ts b/extensions/ql-vscode/src/remote-queries/analyses-results-manager.ts index 8383cabfc..7834a0ecd 100644 --- a/extensions/ql-vscode/src/remote-queries/analyses-results-manager.ts +++ b/extensions/ql-vscode/src/remote-queries/analyses-results-manager.ts @@ -1,3 +1,4 @@ +import * as fs from 'fs-extra'; import * as os from 'os'; import * as path from 'path'; import { CancellationToken, ExtensionContext } from 'vscode'; @@ -12,7 +13,8 @@ import { sarifParser } from '../sarif-parser'; import { extractAnalysisAlerts } from './sarif-processing'; import { CodeQLCliServer } from '../cli'; import { extractRawResults } from './bqrs-processing'; -import { getErrorMessage } from '../pure/helpers-pure'; +import { asyncFilter, getErrorMessage } from '../pure/helpers-pure'; +import { toDownloadPath } from './download-link'; export class AnalysesResultsManager { // Store for the results of various analyses for each remote query. @@ -44,10 +46,19 @@ export class AnalysesResultsManager { await this.downloadSingleAnalysisResults(analysisSummary, credentials, publishResults); } - public async downloadAnalysesResults( + /** + * Loads the array analysis results. For each analysis results, if it is not downloaded yet, + * it will be downloaded. If it is already downloaded, it will be loaded into memory. + * If it is already in memory, this will be a no-op. + * + * @param allAnalysesToDownload List of analyses to ensure are downloaded and in memory + * @param token Optional cancellation token + * @param publishResults Optional function to publish the results after loading + */ + public async loadAnalysesResults( allAnalysesToDownload: AnalysisSummary[], - token: CancellationToken | undefined, - publishResults: (analysesResults: AnalysisResults[]) => Promise + token?: CancellationToken, + publishResults: (analysesResults: AnalysisResults[]) => Promise = () => Promise.resolve() ): Promise { // Filter out analyses that we have already in memory. const analysesToDownload = allAnalysesToDownload.filter(x => !this.isAnalysisInMemory(x)); @@ -151,6 +162,27 @@ export class AnalysesResultsManager { void publishResults([...resultsForQuery]); } + + public async loadDownloadedArtifacts( + allAnalysesToCheck: AnalysisSummary[] + ) { + const allDownloadedAnalyses = await asyncFilter(allAnalysesToCheck, x => this.isDownloadedNotInMemory(x)); + await this.loadAnalysesResults(allDownloadedAnalyses); + } + + private async isDownloadedNotInMemory(analysis: AnalysisSummary): Promise { + const queryId = analysis.downloadLink.queryId; + const resultsForQuery = this.internalGetAnalysesResults(queryId); + const analysisResults = resultsForQuery.find(r => r.nwo === analysis.nwo); + if (analysisResults) { + // We already have the results for this analysis in memory, no need to check further. + return false; + } + + // Check if the analysis results are already downloaded, but not in memory + return await fs.pathExists(toDownloadPath(this.storagePath, analysis.downloadLink)); + } + private async readBqrsResults(filePath: string, fileLinkPrefix: string): Promise { return await extractRawResults(this.cliServer, this.logger, filePath, fileLinkPrefix); } diff --git a/extensions/ql-vscode/src/remote-queries/download-link.ts b/extensions/ql-vscode/src/remote-queries/download-link.ts index 2424f4f6f..52dd7ffcf 100644 --- a/extensions/ql-vscode/src/remote-queries/download-link.ts +++ b/extensions/ql-vscode/src/remote-queries/download-link.ts @@ -1,3 +1,5 @@ +import * as path from 'path'; + /** * Represents a link to an artifact to be downloaded. */ @@ -23,3 +25,16 @@ export interface DownloadLink { */ queryId: string; } + +/** + * Converts a downloadLink to the path where the artifact should be stored. + * + * @param storagePath The base directory to store artifacts in. + * @param downloadLink The DownloadLink + * @param extension An optional file extension to append to the artifact (no `.`). + * + * @returns A full path to the download location of the artifact + */ +export function toDownloadPath(storagePath: string, downloadLink: DownloadLink, extension = '') { + return path.join(storagePath, downloadLink.queryId, downloadLink.id + (extension ? `.${extension}` : '')); +} diff --git a/extensions/ql-vscode/src/remote-queries/gh-actions-api-client.ts b/extensions/ql-vscode/src/remote-queries/gh-actions-api-client.ts index cc35ddb7f..33e670f0b 100644 --- a/extensions/ql-vscode/src/remote-queries/gh-actions-api-client.ts +++ b/extensions/ql-vscode/src/remote-queries/gh-actions-api-client.ts @@ -5,7 +5,7 @@ import { showAndLogWarningMessage, tmpDir } from '../helpers'; import { Credentials } from '../authentication'; import { logger } from '../logging'; import { RemoteQueryWorkflowResult } from './remote-query-workflow-result'; -import { DownloadLink } from './download-link'; +import { DownloadLink, toDownloadPath } from './download-link'; import { RemoteQuery } from './remote-query'; import { RemoteQueryFailureIndexItem, RemoteQueryResultIndex, RemoteQuerySuccessIndexItem } from './remote-query-result-index'; @@ -82,14 +82,14 @@ export async function downloadArtifactFromLink( const octokit = await credentials.getOctokit(); - const extractedPath = path.join(storagePath, downloadLink.queryId, downloadLink.id); + const extractedPath = toDownloadPath(storagePath, downloadLink); // first check if we already have the artifact if (!(await fs.pathExists(extractedPath))) { // Download the zipped artifact. const response = await octokit.request(`GET ${downloadLink.urlPath}/zip`, {}); - const zipFilePath = path.join(storagePath, downloadLink.queryId, `${downloadLink.id}.zip`); + const zipFilePath = toDownloadPath(storagePath, downloadLink, 'zip'); await saveFile(`${zipFilePath}`, response.data as ArrayBuffer); // Extract the zipped artifact. diff --git a/extensions/ql-vscode/src/remote-queries/remote-queries-interface.ts b/extensions/ql-vscode/src/remote-queries/remote-queries-interface.ts index 1c7de4b8e..e48fbb590 100644 --- a/extensions/ql-vscode/src/remote-queries/remote-queries-interface.ts +++ b/extensions/ql-vscode/src/remote-queries/remote-queries-interface.ts @@ -48,7 +48,7 @@ export class RemoteQueriesInterfaceManager { await this.waitForPanelLoaded(); await this.postMessage({ t: 'setRemoteQueryResult', - queryResult: this.buildViewModel(query, queryResult) + queryResult: await this.buildViewModel(query, queryResult) }); await this.setAnalysisResults(this.analysesResultsManager.getAnalysesResults(queryResult.queryId)); @@ -62,14 +62,14 @@ export class RemoteQueriesInterfaceManager { * @param queryResult The result of the query. * @returns A fully created view model. */ - private buildViewModel(query: RemoteQuery, queryResult: RemoteQueryResult): RemoteQueryResultViewModel { + private async buildViewModel(query: RemoteQuery, queryResult: RemoteQueryResult): Promise { const queryFileName = path.basename(query.queryFilePath); const totalResultCount = queryResult.analysisSummaries.reduce((acc, cur) => acc + cur.resultCount, 0); const executionDuration = this.getDuration(queryResult.executionEndTime, query.executionStartTime); const analysisSummaries = this.buildAnalysisSummaries(queryResult.analysisSummaries); const affectedRepositories = queryResult.analysisSummaries.filter(r => r.resultCount > 0); - return { + const model = { queryTitle: query.queryName, queryFileName: queryFileName, queryFilePath: query.queryFilePath, @@ -84,6 +84,10 @@ export class RemoteQueriesInterfaceManager { analysisSummaries: analysisSummaries, analysisFailures: queryResult.analysisFailures, }; + + // Ensure all pre-downloaded artifacts are loaded into memory + await this.analysesResultsManager.loadDownloadedArtifacts(model.analysisSummaries); + return model; } getPanel(): WebviewPanel { @@ -213,7 +217,7 @@ export class RemoteQueriesInterfaceManager { } private async downloadAllAnalysesResults(msg: RemoteQueryDownloadAllAnalysesResultsMessage): Promise { - await this.analysesResultsManager.downloadAnalysesResults( + await this.analysesResultsManager.loadAnalysesResults( msg.analysisSummaries, undefined, results => this.setAnalysisResults(results)); diff --git a/extensions/ql-vscode/src/remote-queries/remote-queries-manager.ts b/extensions/ql-vscode/src/remote-queries/remote-queries-manager.ts index d5da39a7e..6fd973f4e 100644 --- a/extensions/ql-vscode/src/remote-queries/remote-queries-manager.ts +++ b/extensions/ql-vscode/src/remote-queries/remote-queries-manager.ts @@ -187,7 +187,7 @@ export class RemoteQueriesManager extends DisposableObject { fileSize: String(a.fileSizeInBytes) })); - await this.analysesResultsManager.downloadAnalysesResults( + await this.analysesResultsManager.loadAnalysesResults( analysesToDownload, token, results => this.interfaceManager.setAnalysisResults(results)); diff --git a/extensions/ql-vscode/src/remote-queries/sarif-processing.ts b/extensions/ql-vscode/src/remote-queries/sarif-processing.ts index d4ca0daea..e77535a32 100644 --- a/extensions/ql-vscode/src/remote-queries/sarif-processing.ts +++ b/extensions/ql-vscode/src/remote-queries/sarif-processing.ts @@ -157,6 +157,15 @@ export function tryGetRule( } function getCodeSnippet(region: sarif.Region): CodeSnippet { + + if (!region) { + // Handle SARIF generated from queries that do not have a region. + return { + startLine: 1, + endLine: 1, + text: '' + }; + } const text = region.snippet!.text!; const { startLine, endLine } = parseSarifRegion(region); @@ -175,7 +184,7 @@ function getHighlightedRegion(region: sarif.Region): HighlightedRegion { startColumn, endLine, - // parseSarifRegion currently shifts the end column by 1 to account + // parseSarifRegion currently shifts the end column by 1 to account // for the way vscode counts columns so we need to shift it back. endColumn: endColumn + 1 }; diff --git a/extensions/ql-vscode/src/vscode-tests/no-workspace/data/remote-queries/queries/MRVA Integration test 1-6sBi6oaky_fxqXW2NA4bx/query-result.json b/extensions/ql-vscode/src/vscode-tests/no-workspace/data/remote-queries/queries/MRVA Integration test 1-6sBi6oaky_fxqXW2NA4bx/query-result.json index ca201b528..24218e5c1 100644 --- a/extensions/ql-vscode/src/vscode-tests/no-workspace/data/remote-queries/queries/MRVA Integration test 1-6sBi6oaky_fxqXW2NA4bx/query-result.json +++ b/extensions/ql-vscode/src/vscode-tests/no-workspace/data/remote-queries/queries/MRVA Integration test 1-6sBi6oaky_fxqXW2NA4bx/query-result.json @@ -22,6 +22,17 @@ "innerFilePath": "results.sarif", "queryId": "MRVA Integration test 1-6sBi6oaky_fxqXW2NA4bx" } + }, + { + "nwo": "hucairz/i-dont-exist", + "resultCount": 5, + "fileSizeInBytes": 81237, + "downloadLink": { + "id": "999999", + "urlPath": "/these/results/will/never/be/downloaded/999999", + "innerFilePath": "results.sarif", + "queryId": "MRVA Integration test 2-UL-vbKAjP8ffObxjsp7hN" + } } ], "analysisFailures": [], diff --git a/extensions/ql-vscode/src/vscode-tests/no-workspace/download-link.test.ts b/extensions/ql-vscode/src/vscode-tests/no-workspace/download-link.test.ts new file mode 100644 index 000000000..17a5e2afd --- /dev/null +++ b/extensions/ql-vscode/src/vscode-tests/no-workspace/download-link.test.ts @@ -0,0 +1,31 @@ +import { expect } from 'chai'; +import 'mocha'; +import * as path from 'path'; + +import { DownloadLink, toDownloadPath } from '../../remote-queries/download-link'; + +describe('toDownloadPath', () => { + it('should return the correct path', () => { + const downloadLink: DownloadLink = { + id: 'abc', + urlPath: '', + innerFilePath: '', + queryId: 'def' + }; + + const expectedPath = path.join('storage', 'def', 'abc'); + expect(toDownloadPath('storage', downloadLink)).to.equal(expectedPath); + }); + + it('should return the correct path with extension', () => { + const downloadLink: DownloadLink = { + id: 'abc', + urlPath: '', + innerFilePath: '', + queryId: 'def' + }; + + const expectedPath = path.join('storage', 'def', 'abc.zip'); + expect(toDownloadPath('storage', downloadLink, 'zip')).to.equal(expectedPath); + }); +}); diff --git a/extensions/ql-vscode/src/vscode-tests/no-workspace/remote-query-history.test.ts b/extensions/ql-vscode/src/vscode-tests/no-workspace/remote-query-history.test.ts index 448ff8f96..4302c0e88 100644 --- a/extensions/ql-vscode/src/vscode-tests/no-workspace/remote-query-history.test.ts +++ b/extensions/ql-vscode/src/vscode-tests/no-workspace/remote-query-history.test.ts @@ -245,8 +245,8 @@ describe('Remote queries and query history manager', function() { it('should download two artifacts at once', async () => { const publisher = sandbox.spy(); - const analysisSummaries = [...remoteQueryResult0.analysisSummaries]; - await arm.downloadAnalysesResults(analysisSummaries, undefined, publisher); + const analysisSummaries = [remoteQueryResult0.analysisSummaries[0], remoteQueryResult0.analysisSummaries[1]]; + await arm.loadAnalysesResults(analysisSummaries, undefined, publisher); const trimmed = publisher.getCalls().map(call => call.args[0]).map(args => { args.forEach((analysisResult: any) => delete analysisResult.interpretedResults); @@ -287,7 +287,7 @@ describe('Remote queries and query history manager', function() { const analysisSummaries = [...remoteQueryResult0.analysisSummaries]; try { - await arm.downloadAnalysesResults(analysisSummaries, { + await arm.loadAnalysesResults(analysisSummaries, { isCancellationRequested: true } as CancellationToken, publisher); expect.fail('Should have thrown'); @@ -300,11 +300,11 @@ describe('Remote queries and query history manager', function() { it('should get the analysis results', async () => { const publisher = sandbox.spy(); - const analysisSummaries0 = [...remoteQueryResult0.analysisSummaries]; + const analysisSummaries0 = [remoteQueryResult0.analysisSummaries[0], remoteQueryResult0.analysisSummaries[1]]; const analysisSummaries1 = [...remoteQueryResult1.analysisSummaries]; - await arm.downloadAnalysesResults(analysisSummaries0, undefined, publisher); - await arm.downloadAnalysesResults(analysisSummaries1, undefined, publisher); + await arm.loadAnalysesResults(analysisSummaries0, undefined, publisher); + await arm.loadAnalysesResults(analysisSummaries1, undefined, publisher); const result0 = arm.getAnalysesResults(rawQueryHistory[0].queryId); const result0Again = arm.getAnalysesResults(rawQueryHistory[0].queryId); @@ -323,7 +323,7 @@ describe('Remote queries and query history manager', function() { it.skip('should read sarif', async () => { const publisher = sandbox.spy(); const analysisSummaries0 = [remoteQueryResult0.analysisSummaries[0]]; - await arm.downloadAnalysesResults(analysisSummaries0, undefined, publisher); + await arm.loadAnalysesResults(analysisSummaries0, undefined, publisher); const sarif = fs.readJSONSync(path.join(STORAGE_DIR, 'queries', rawQueryHistory[0].queryId, '171543249', 'results.sarif')); const queryResults = sarif.runs @@ -332,6 +332,28 @@ describe('Remote queries and query history manager', function() { expect(publisher.getCall(1).args[0][0].results).to.deep.eq(queryResults); }); + + it('should check if an artifact is downloaded and not in memory', async () => { + // Load remoteQueryResult0.analysisSummaries[1] into memory + await arm.downloadAnalysisResults(remoteQueryResult0.analysisSummaries[1], () => Promise.resolve()); + + expect(await (arm as any).isDownloadedNotInMemory(remoteQueryResult0.analysisSummaries[0])).to.be.true; + + // in memory + expect(await (arm as any).isDownloadedNotInMemory(remoteQueryResult0.analysisSummaries[1])).to.be.false; + + // not downloaded + expect(await (arm as any).isDownloadedNotInMemory(remoteQueryResult0.analysisSummaries[2])).to.be.false; + }); + + it('should load downloaded artifacts', async () => { + await arm.loadDownloadedArtifacts(remoteQueryResult0.analysisSummaries); + const queryId = rawQueryHistory[0].queryId; + const analysesResultsNwos = arm.getAnalysesResults(queryId).map(ar => ar.nwo).sort(); + expect(analysesResultsNwos[0]).to.eq('github/vscode-codeql'); + expect(analysesResultsNwos[1]).to.eq('other/hucairz'); + expect(analysesResultsNwos.length).to.eq(2); + }); }); async function copyHistoryState() { diff --git a/extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts b/extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts index 16eb6dace..339c33050 100644 --- a/extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts +++ b/extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts @@ -421,7 +421,7 @@ describe('SARIF processing', () => { it('should return errors for result locations with no context region', () => { const sarif = buildValidSarifLog(); - sarif.runs![0]!.results![0]!.locations![0]!.physicalLocation!.contextRegion = undefined; + sarif.runs![0]!.results![0]!.locations![0]!.physicalLocation!.contextRegion!.snippet = undefined; const result = extractAnalysisAlerts(sarif, fakefileLinkPrefix); @@ -597,7 +597,7 @@ describe('SARIF processing', () => { function buildValidSarifLog(): sarif.Log { return { - version: '0.0.1' as sarif.Log.version, + version: '2.1.0', runs: [ { results: [ From ffe7fdcb461046533fcc260c97da853ed0eb4c21 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Tue, 29 Mar 2022 13:04:00 -0700 Subject: [PATCH 2/4] Rename methods and address comments --- .../analyses-results-manager.ts | 14 +++--- .../src/remote-queries/download-link.ts | 2 +- .../remote-queries/gh-actions-api-client.ts | 6 +-- .../remote-queries-interface.ts | 12 ++--- .../src/remote-queries/sarif-processing.ts | 21 ++++----- .../remote-queries/shared/analysis-result.ts | 2 +- .../remote-queries/view/FileCodeSnippet.tsx | 8 ++-- .../no-workspace/download-link.test.ts | 13 ++++-- .../test/pure-tests/sarif-processing.test.ts | 45 ++++++++++++++++--- 9 files changed, 79 insertions(+), 44 deletions(-) diff --git a/extensions/ql-vscode/src/remote-queries/analyses-results-manager.ts b/extensions/ql-vscode/src/remote-queries/analyses-results-manager.ts index 7834a0ecd..7f65c0a4e 100644 --- a/extensions/ql-vscode/src/remote-queries/analyses-results-manager.ts +++ b/extensions/ql-vscode/src/remote-queries/analyses-results-manager.ts @@ -14,7 +14,7 @@ import { extractAnalysisAlerts } from './sarif-processing'; import { CodeQLCliServer } from '../cli'; import { extractRawResults } from './bqrs-processing'; import { asyncFilter, getErrorMessage } from '../pure/helpers-pure'; -import { toDownloadPath } from './download-link'; +import { createDownloadPath } from './download-link'; export class AnalysesResultsManager { // Store for the results of various analyses for each remote query. @@ -51,17 +51,17 @@ export class AnalysesResultsManager { * it will be downloaded. If it is already downloaded, it will be loaded into memory. * If it is already in memory, this will be a no-op. * - * @param allAnalysesToDownload List of analyses to ensure are downloaded and in memory + * @param allAnalysesToLoad List of analyses to ensure are downloaded and in memory * @param token Optional cancellation token * @param publishResults Optional function to publish the results after loading */ public async loadAnalysesResults( - allAnalysesToDownload: AnalysisSummary[], + allAnalysesToLoad: AnalysisSummary[], token?: CancellationToken, publishResults: (analysesResults: AnalysisResults[]) => Promise = () => Promise.resolve() ): Promise { // Filter out analyses that we have already in memory. - const analysesToDownload = allAnalysesToDownload.filter(x => !this.isAnalysisInMemory(x)); + const analysesToDownload = allAnalysesToLoad.filter(x => !this.isAnalysisInMemory(x)); const credentials = await Credentials.initialize(this.ctx); @@ -166,11 +166,11 @@ export class AnalysesResultsManager { public async loadDownloadedArtifacts( allAnalysesToCheck: AnalysisSummary[] ) { - const allDownloadedAnalyses = await asyncFilter(allAnalysesToCheck, x => this.isDownloadedNotInMemory(x)); + const allDownloadedAnalyses = await asyncFilter(allAnalysesToCheck, x => this.isAnalysisDownloadedNotInMemory(x)); await this.loadAnalysesResults(allDownloadedAnalyses); } - private async isDownloadedNotInMemory(analysis: AnalysisSummary): Promise { + private async isAnalysisDownloadedNotInMemory(analysis: AnalysisSummary): Promise { const queryId = analysis.downloadLink.queryId; const resultsForQuery = this.internalGetAnalysesResults(queryId); const analysisResults = resultsForQuery.find(r => r.nwo === analysis.nwo); @@ -180,7 +180,7 @@ export class AnalysesResultsManager { } // Check if the analysis results are already downloaded, but not in memory - return await fs.pathExists(toDownloadPath(this.storagePath, analysis.downloadLink)); + return await fs.pathExists(createDownloadPath(this.storagePath, analysis.downloadLink)); } private async readBqrsResults(filePath: string, fileLinkPrefix: string): Promise { diff --git a/extensions/ql-vscode/src/remote-queries/download-link.ts b/extensions/ql-vscode/src/remote-queries/download-link.ts index 52dd7ffcf..dffef7b2b 100644 --- a/extensions/ql-vscode/src/remote-queries/download-link.ts +++ b/extensions/ql-vscode/src/remote-queries/download-link.ts @@ -35,6 +35,6 @@ export interface DownloadLink { * * @returns A full path to the download location of the artifact */ -export function toDownloadPath(storagePath: string, downloadLink: DownloadLink, extension = '') { +export function createDownloadPath(storagePath: string, downloadLink: DownloadLink, extension = '') { return path.join(storagePath, downloadLink.queryId, downloadLink.id + (extension ? `.${extension}` : '')); } diff --git a/extensions/ql-vscode/src/remote-queries/gh-actions-api-client.ts b/extensions/ql-vscode/src/remote-queries/gh-actions-api-client.ts index 33e670f0b..16bfbc574 100644 --- a/extensions/ql-vscode/src/remote-queries/gh-actions-api-client.ts +++ b/extensions/ql-vscode/src/remote-queries/gh-actions-api-client.ts @@ -5,7 +5,7 @@ import { showAndLogWarningMessage, tmpDir } from '../helpers'; import { Credentials } from '../authentication'; import { logger } from '../logging'; import { RemoteQueryWorkflowResult } from './remote-query-workflow-result'; -import { DownloadLink, toDownloadPath } from './download-link'; +import { DownloadLink, createDownloadPath } from './download-link'; import { RemoteQuery } from './remote-query'; import { RemoteQueryFailureIndexItem, RemoteQueryResultIndex, RemoteQuerySuccessIndexItem } from './remote-query-result-index'; @@ -82,14 +82,14 @@ export async function downloadArtifactFromLink( const octokit = await credentials.getOctokit(); - const extractedPath = toDownloadPath(storagePath, downloadLink); + const extractedPath = createDownloadPath(storagePath, downloadLink); // first check if we already have the artifact if (!(await fs.pathExists(extractedPath))) { // Download the zipped artifact. const response = await octokit.request(`GET ${downloadLink.urlPath}/zip`, {}); - const zipFilePath = toDownloadPath(storagePath, downloadLink, 'zip'); + const zipFilePath = createDownloadPath(storagePath, downloadLink, 'zip'); await saveFile(`${zipFilePath}`, response.data as ArrayBuffer); // Extract the zipped artifact. diff --git a/extensions/ql-vscode/src/remote-queries/remote-queries-interface.ts b/extensions/ql-vscode/src/remote-queries/remote-queries-interface.ts index e48fbb590..9392a3cb8 100644 --- a/extensions/ql-vscode/src/remote-queries/remote-queries-interface.ts +++ b/extensions/ql-vscode/src/remote-queries/remote-queries-interface.ts @@ -46,11 +46,15 @@ export class RemoteQueriesInterfaceManager { this.getPanel().reveal(undefined, true); await this.waitForPanelLoaded(); + const model = await this.buildViewModel(query, queryResult); await this.postMessage({ t: 'setRemoteQueryResult', - queryResult: await this.buildViewModel(query, queryResult) + queryResult: model }); + // Ensure all pre-downloaded artifacts are loaded into memory + await this.analysesResultsManager.loadDownloadedArtifacts(model.analysisSummaries); + await this.setAnalysisResults(this.analysesResultsManager.getAnalysesResults(queryResult.queryId)); } @@ -69,7 +73,7 @@ export class RemoteQueriesInterfaceManager { const analysisSummaries = this.buildAnalysisSummaries(queryResult.analysisSummaries); const affectedRepositories = queryResult.analysisSummaries.filter(r => r.resultCount > 0); - const model = { + return { queryTitle: query.queryName, queryFileName: queryFileName, queryFilePath: query.queryFilePath, @@ -84,10 +88,6 @@ export class RemoteQueriesInterfaceManager { analysisSummaries: analysisSummaries, analysisFailures: queryResult.analysisFailures, }; - - // Ensure all pre-downloaded artifacts are loaded into memory - await this.analysesResultsManager.loadDownloadedArtifacts(model.analysisSummaries); - return model; } getPanel(): WebviewPanel { diff --git a/extensions/ql-vscode/src/remote-queries/sarif-processing.ts b/extensions/ql-vscode/src/remote-queries/sarif-processing.ts index e77535a32..bb4ef6d5a 100644 --- a/extensions/ql-vscode/src/remote-queries/sarif-processing.ts +++ b/extensions/ql-vscode/src/remote-queries/sarif-processing.ts @@ -54,9 +54,9 @@ function extractResultAlerts( for (const location of result.locations ?? []) { const physicalLocation = location.physicalLocation!; const filePath = physicalLocation.artifactLocation!.uri!; - const codeSnippet = getCodeSnippet(physicalLocation.contextRegion!); + const codeSnippet = getCodeSnippet(physicalLocation.contextRegion, physicalLocation.region); const highlightedRegion = physicalLocation.region - ? getHighlightedRegion(physicalLocation.region!) + ? getHighlightedRegion(physicalLocation.region) : undefined; const analysisAlert: AnalysisAlert = { @@ -156,24 +156,21 @@ export function tryGetRule( return undefined; } -function getCodeSnippet(region: sarif.Region): CodeSnippet { +function getCodeSnippet(region?: sarif.Region, alternateRegion?: sarif.Region): CodeSnippet | undefined { + region = region ?? alternateRegion; if (!region) { - // Handle SARIF generated from queries that do not have a region. - return { - startLine: 1, - endLine: 1, - text: '' - }; + return undefined; } - const text = region.snippet!.text!; + + const text = region.snippet?.text || ''; const { startLine, endLine } = parseSarifRegion(region); return { startLine, endLine, text - } as CodeSnippet; + }; } function getHighlightedRegion(region: sarif.Region): HighlightedRegion { @@ -204,7 +201,7 @@ function getCodeFlows( for (const threadFlowLocation of threadFlow.locations) { const physicalLocation = threadFlowLocation!.location!.physicalLocation!; const filePath = physicalLocation!.artifactLocation!.uri!; - const codeSnippet = getCodeSnippet(physicalLocation.contextRegion!); + const codeSnippet = getCodeSnippet(physicalLocation.contextRegion, physicalLocation.region); const highlightedRegion = physicalLocation.region ? getHighlightedRegion(physicalLocation.region) : undefined; diff --git a/extensions/ql-vscode/src/remote-queries/shared/analysis-result.ts b/extensions/ql-vscode/src/remote-queries/shared/analysis-result.ts index f8d7613ad..c40088391 100644 --- a/extensions/ql-vscode/src/remote-queries/shared/analysis-result.ts +++ b/extensions/ql-vscode/src/remote-queries/shared/analysis-result.ts @@ -21,7 +21,7 @@ export interface AnalysisAlert { shortDescription: string; severity: ResultSeverity; fileLink: FileLink; - codeSnippet: CodeSnippet; + codeSnippet?: CodeSnippet; highlightedRegion?: HighlightedRegion; codeFlows: CodeFlow[]; } diff --git a/extensions/ql-vscode/src/remote-queries/view/FileCodeSnippet.tsx b/extensions/ql-vscode/src/remote-queries/view/FileCodeSnippet.tsx index d68de0721..05a32ab75 100644 --- a/extensions/ql-vscode/src/remote-queries/view/FileCodeSnippet.tsx +++ b/extensions/ql-vscode/src/remote-queries/view/FileCodeSnippet.tsx @@ -181,17 +181,17 @@ const FileCodeSnippet = ({ messageChildren, }: { fileLink: FileLink, - codeSnippet: CodeSnippet, + codeSnippet?: CodeSnippet, highlightedRegion?: HighlightedRegion, severity?: ResultSeverity, message?: AnalysisMessage, messageChildren?: React.ReactNode, }) => { - const code = codeSnippet.text.split('\n'); + const code = codeSnippet?.text.split('\n') || []; - const startingLine = codeSnippet.startLine; - const endingLine = codeSnippet.endLine; + const startingLine = codeSnippet?.startLine || 0; + const endingLine = codeSnippet?.endLine || 0; const titleFileUri = createRemoteFileRef( fileLink, diff --git a/extensions/ql-vscode/src/vscode-tests/no-workspace/download-link.test.ts b/extensions/ql-vscode/src/vscode-tests/no-workspace/download-link.test.ts index 17a5e2afd..c1262bf00 100644 --- a/extensions/ql-vscode/src/vscode-tests/no-workspace/download-link.test.ts +++ b/extensions/ql-vscode/src/vscode-tests/no-workspace/download-link.test.ts @@ -2,7 +2,7 @@ import { expect } from 'chai'; import 'mocha'; import * as path from 'path'; -import { DownloadLink, toDownloadPath } from '../../remote-queries/download-link'; +import { DownloadLink, createDownloadPath } from '../../remote-queries/download-link'; describe('toDownloadPath', () => { it('should return the correct path', () => { @@ -12,9 +12,11 @@ describe('toDownloadPath', () => { innerFilePath: '', queryId: 'def' }; - const expectedPath = path.join('storage', 'def', 'abc'); - expect(toDownloadPath('storage', downloadLink)).to.equal(expectedPath); + + const actualPath = createDownloadPath('storage', downloadLink); + + expect(actualPath).to.equal(expectedPath); }); it('should return the correct path with extension', () => { @@ -26,6 +28,9 @@ describe('toDownloadPath', () => { }; const expectedPath = path.join('storage', 'def', 'abc.zip'); - expect(toDownloadPath('storage', downloadLink, 'zip')).to.equal(expectedPath); + + const actualPath = createDownloadPath('storage', downloadLink, 'zip'); + + expect(actualPath).to.equal(expectedPath); }); }); diff --git a/extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts b/extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts index 339c33050..3a9fb5138 100644 --- a/extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts +++ b/extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts @@ -419,15 +419,42 @@ describe('SARIF processing', () => { expectResultParsingError(result.errors[0]); }); - it('should return errors for result locations with no context region', () => { + it('should not return errors for result locations with no snippet', () => { const sarif = buildValidSarifLog(); sarif.runs![0]!.results![0]!.locations![0]!.physicalLocation!.contextRegion!.snippet = undefined; const result = extractAnalysisAlerts(sarif, fakefileLinkPrefix); + const expectedCodeSnippet = { + startLine: result.alerts[0].codeSnippet!.startLine, + endLine: result.alerts[0].codeSnippet!.endLine, + text: '' + }; + + const actualCodeSnippet = result.alerts[0].codeSnippet; + expect(result).to.be.ok; - expect(result.errors.length).to.equal(1); - expectResultParsingError(result.errors[0]); + expectNoParsingError(result); + expect(actualCodeSnippet).to.deep.equal(expectedCodeSnippet); + }); + + it('should not return errors for result locations with no contextRegion', () => { + const sarif = buildValidSarifLog(); + sarif.runs![0]!.results![0]!.locations![0]!.physicalLocation!.contextRegion = undefined; + + const result = extractAnalysisAlerts(sarif, fakefileLinkPrefix); + + const expectedCodeSnippet = { + startLine: result.alerts[0].highlightedRegion!.startLine, + endLine: result.alerts[0].highlightedRegion!.endLine, + text: '' + }; + + const actualCodeSnippet = result.alerts[0].codeSnippet; + + expect(result).to.be.ok; + expectNoParsingError(result); + expect(actualCodeSnippet).to.deep.equal(expectedCodeSnippet); }); it('should not return errors for result locations with no region', () => { @@ -438,6 +465,7 @@ describe('SARIF processing', () => { expect(result).to.be.ok; expect(result.alerts.length).to.equal(1); + expectNoParsingError(result); }); it('should return errors for result locations with no physical location', () => { @@ -537,9 +565,9 @@ describe('SARIF processing', () => { expect(result).to.be.ok; expect(result.errors.length).to.equal(0); expect(result.alerts.length).to.equal(3); - expect(result.alerts.find(a => getMessageText(a.message) === 'msg1' && a.codeSnippet.text === 'foo')).to.be.ok; - expect(result.alerts.find(a => getMessageText(a.message) === 'msg1' && a.codeSnippet.text === 'bar')).to.be.ok; - expect(result.alerts.find(a => getMessageText(a.message) === 'msg2' && a.codeSnippet.text === 'baz')).to.be.ok; + expect(result.alerts.find(a => getMessageText(a.message) === 'msg1' && a.codeSnippet!.text === 'foo')).to.be.ok; + expect(result.alerts.find(a => getMessageText(a.message) === 'msg1' && a.codeSnippet!.text === 'bar')).to.be.ok; + expect(result.alerts.find(a => getMessageText(a.message) === 'msg2' && a.codeSnippet!.text === 'baz')).to.be.ok; expect(result.alerts.every(a => a.severity === 'Warning')).to.be.true; }); @@ -595,6 +623,11 @@ describe('SARIF processing', () => { expect(msg.startsWith('Error when processing SARIF result')).to.be.true; } + function expectNoParsingError(result: { errors: string[] | undefined }) { + const array = result.errors || []; + expect(array.length, array.join()).to.equal(0); + } + function buildValidSarifLog(): sarif.Log { return { version: '2.1.0', From 006cc8c52a9ef4ed47e29b44c14468a1ddf5ca78 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Tue, 29 Mar 2022 13:06:44 -0700 Subject: [PATCH 3/4] Undo sarif-processing change Will move to a different PR. --- .../src/remote-queries/sarif-processing.ts | 20 +++----- .../remote-queries/shared/analysis-result.ts | 2 +- .../remote-queries/view/FileCodeSnippet.tsx | 8 ++-- .../test/pure-tests/sarif-processing.test.ts | 47 +++---------------- 4 files changed, 19 insertions(+), 58 deletions(-) diff --git a/extensions/ql-vscode/src/remote-queries/sarif-processing.ts b/extensions/ql-vscode/src/remote-queries/sarif-processing.ts index bb4ef6d5a..d4ca0daea 100644 --- a/extensions/ql-vscode/src/remote-queries/sarif-processing.ts +++ b/extensions/ql-vscode/src/remote-queries/sarif-processing.ts @@ -54,9 +54,9 @@ function extractResultAlerts( for (const location of result.locations ?? []) { const physicalLocation = location.physicalLocation!; const filePath = physicalLocation.artifactLocation!.uri!; - const codeSnippet = getCodeSnippet(physicalLocation.contextRegion, physicalLocation.region); + const codeSnippet = getCodeSnippet(physicalLocation.contextRegion!); const highlightedRegion = physicalLocation.region - ? getHighlightedRegion(physicalLocation.region) + ? getHighlightedRegion(physicalLocation.region!) : undefined; const analysisAlert: AnalysisAlert = { @@ -156,21 +156,15 @@ export function tryGetRule( return undefined; } -function getCodeSnippet(region?: sarif.Region, alternateRegion?: sarif.Region): CodeSnippet | undefined { - region = region ?? alternateRegion; - - if (!region) { - return undefined; - } - - const text = region.snippet?.text || ''; +function getCodeSnippet(region: sarif.Region): CodeSnippet { + const text = region.snippet!.text!; const { startLine, endLine } = parseSarifRegion(region); return { startLine, endLine, text - }; + } as CodeSnippet; } function getHighlightedRegion(region: sarif.Region): HighlightedRegion { @@ -181,7 +175,7 @@ function getHighlightedRegion(region: sarif.Region): HighlightedRegion { startColumn, endLine, - // parseSarifRegion currently shifts the end column by 1 to account + // parseSarifRegion currently shifts the end column by 1 to account // for the way vscode counts columns so we need to shift it back. endColumn: endColumn + 1 }; @@ -201,7 +195,7 @@ function getCodeFlows( for (const threadFlowLocation of threadFlow.locations) { const physicalLocation = threadFlowLocation!.location!.physicalLocation!; const filePath = physicalLocation!.artifactLocation!.uri!; - const codeSnippet = getCodeSnippet(physicalLocation.contextRegion, physicalLocation.region); + const codeSnippet = getCodeSnippet(physicalLocation.contextRegion!); const highlightedRegion = physicalLocation.region ? getHighlightedRegion(physicalLocation.region) : undefined; diff --git a/extensions/ql-vscode/src/remote-queries/shared/analysis-result.ts b/extensions/ql-vscode/src/remote-queries/shared/analysis-result.ts index c40088391..f8d7613ad 100644 --- a/extensions/ql-vscode/src/remote-queries/shared/analysis-result.ts +++ b/extensions/ql-vscode/src/remote-queries/shared/analysis-result.ts @@ -21,7 +21,7 @@ export interface AnalysisAlert { shortDescription: string; severity: ResultSeverity; fileLink: FileLink; - codeSnippet?: CodeSnippet; + codeSnippet: CodeSnippet; highlightedRegion?: HighlightedRegion; codeFlows: CodeFlow[]; } diff --git a/extensions/ql-vscode/src/remote-queries/view/FileCodeSnippet.tsx b/extensions/ql-vscode/src/remote-queries/view/FileCodeSnippet.tsx index 05a32ab75..d68de0721 100644 --- a/extensions/ql-vscode/src/remote-queries/view/FileCodeSnippet.tsx +++ b/extensions/ql-vscode/src/remote-queries/view/FileCodeSnippet.tsx @@ -181,17 +181,17 @@ const FileCodeSnippet = ({ messageChildren, }: { fileLink: FileLink, - codeSnippet?: CodeSnippet, + codeSnippet: CodeSnippet, highlightedRegion?: HighlightedRegion, severity?: ResultSeverity, message?: AnalysisMessage, messageChildren?: React.ReactNode, }) => { - const code = codeSnippet?.text.split('\n') || []; + const code = codeSnippet.text.split('\n'); - const startingLine = codeSnippet?.startLine || 0; - const endingLine = codeSnippet?.endLine || 0; + const startingLine = codeSnippet.startLine; + const endingLine = codeSnippet.endLine; const titleFileUri = createRemoteFileRef( fileLink, diff --git a/extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts b/extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts index 3a9fb5138..16eb6dace 100644 --- a/extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts +++ b/extensions/ql-vscode/test/pure-tests/sarif-processing.test.ts @@ -419,42 +419,15 @@ describe('SARIF processing', () => { expectResultParsingError(result.errors[0]); }); - it('should not return errors for result locations with no snippet', () => { - const sarif = buildValidSarifLog(); - sarif.runs![0]!.results![0]!.locations![0]!.physicalLocation!.contextRegion!.snippet = undefined; - - const result = extractAnalysisAlerts(sarif, fakefileLinkPrefix); - - const expectedCodeSnippet = { - startLine: result.alerts[0].codeSnippet!.startLine, - endLine: result.alerts[0].codeSnippet!.endLine, - text: '' - }; - - const actualCodeSnippet = result.alerts[0].codeSnippet; - - expect(result).to.be.ok; - expectNoParsingError(result); - expect(actualCodeSnippet).to.deep.equal(expectedCodeSnippet); - }); - - it('should not return errors for result locations with no contextRegion', () => { + it('should return errors for result locations with no context region', () => { const sarif = buildValidSarifLog(); sarif.runs![0]!.results![0]!.locations![0]!.physicalLocation!.contextRegion = undefined; const result = extractAnalysisAlerts(sarif, fakefileLinkPrefix); - const expectedCodeSnippet = { - startLine: result.alerts[0].highlightedRegion!.startLine, - endLine: result.alerts[0].highlightedRegion!.endLine, - text: '' - }; - - const actualCodeSnippet = result.alerts[0].codeSnippet; - expect(result).to.be.ok; - expectNoParsingError(result); - expect(actualCodeSnippet).to.deep.equal(expectedCodeSnippet); + expect(result.errors.length).to.equal(1); + expectResultParsingError(result.errors[0]); }); it('should not return errors for result locations with no region', () => { @@ -465,7 +438,6 @@ describe('SARIF processing', () => { expect(result).to.be.ok; expect(result.alerts.length).to.equal(1); - expectNoParsingError(result); }); it('should return errors for result locations with no physical location', () => { @@ -565,9 +537,9 @@ describe('SARIF processing', () => { expect(result).to.be.ok; expect(result.errors.length).to.equal(0); expect(result.alerts.length).to.equal(3); - expect(result.alerts.find(a => getMessageText(a.message) === 'msg1' && a.codeSnippet!.text === 'foo')).to.be.ok; - expect(result.alerts.find(a => getMessageText(a.message) === 'msg1' && a.codeSnippet!.text === 'bar')).to.be.ok; - expect(result.alerts.find(a => getMessageText(a.message) === 'msg2' && a.codeSnippet!.text === 'baz')).to.be.ok; + expect(result.alerts.find(a => getMessageText(a.message) === 'msg1' && a.codeSnippet.text === 'foo')).to.be.ok; + expect(result.alerts.find(a => getMessageText(a.message) === 'msg1' && a.codeSnippet.text === 'bar')).to.be.ok; + expect(result.alerts.find(a => getMessageText(a.message) === 'msg2' && a.codeSnippet.text === 'baz')).to.be.ok; expect(result.alerts.every(a => a.severity === 'Warning')).to.be.true; }); @@ -623,14 +595,9 @@ describe('SARIF processing', () => { expect(msg.startsWith('Error when processing SARIF result')).to.be.true; } - function expectNoParsingError(result: { errors: string[] | undefined }) { - const array = result.errors || []; - expect(array.length, array.join()).to.equal(0); - } - function buildValidSarifLog(): sarif.Log { return { - version: '2.1.0', + version: '0.0.1' as sarif.Log.version, runs: [ { results: [ From 67336a24e7a161e1d3d067d85adfd5620478f2f1 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Wed, 30 Mar 2022 11:30:10 -0700 Subject: [PATCH 4/4] Simplify checking for downloaded analyses And some renaming. --- .../remote-queries/analyses-results-manager.ts | 18 ++++++------------ .../remote-queries/remote-queries-interface.ts | 6 +++--- .../no-workspace/download-link.test.ts | 2 +- .../no-workspace/remote-query-history.test.ts | 9 +++++---- 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/extensions/ql-vscode/src/remote-queries/analyses-results-manager.ts b/extensions/ql-vscode/src/remote-queries/analyses-results-manager.ts index 7f65c0a4e..fcdf849f2 100644 --- a/extensions/ql-vscode/src/remote-queries/analyses-results-manager.ts +++ b/extensions/ql-vscode/src/remote-queries/analyses-results-manager.ts @@ -163,23 +163,17 @@ export class AnalysesResultsManager { } - public async loadDownloadedArtifacts( + public async loadDownloadedAnalyses( allAnalysesToCheck: AnalysisSummary[] ) { - const allDownloadedAnalyses = await asyncFilter(allAnalysesToCheck, x => this.isAnalysisDownloadedNotInMemory(x)); + + // Find all analyses that are already downloaded. + const allDownloadedAnalyses = await asyncFilter(allAnalysesToCheck, x => this.isAnalysisDownloaded(x)); + // Now, ensure that all of these analyses are in memory. Some may already be in memory. These are ignored. await this.loadAnalysesResults(allDownloadedAnalyses); } - private async isAnalysisDownloadedNotInMemory(analysis: AnalysisSummary): Promise { - const queryId = analysis.downloadLink.queryId; - const resultsForQuery = this.internalGetAnalysesResults(queryId); - const analysisResults = resultsForQuery.find(r => r.nwo === analysis.nwo); - if (analysisResults) { - // We already have the results for this analysis in memory, no need to check further. - return false; - } - - // Check if the analysis results are already downloaded, but not in memory + private async isAnalysisDownloaded(analysis: AnalysisSummary): Promise { return await fs.pathExists(createDownloadPath(this.storagePath, analysis.downloadLink)); } diff --git a/extensions/ql-vscode/src/remote-queries/remote-queries-interface.ts b/extensions/ql-vscode/src/remote-queries/remote-queries-interface.ts index 9392a3cb8..da53e6282 100644 --- a/extensions/ql-vscode/src/remote-queries/remote-queries-interface.ts +++ b/extensions/ql-vscode/src/remote-queries/remote-queries-interface.ts @@ -46,14 +46,14 @@ export class RemoteQueriesInterfaceManager { this.getPanel().reveal(undefined, true); await this.waitForPanelLoaded(); - const model = await this.buildViewModel(query, queryResult); + const model = this.buildViewModel(query, queryResult); await this.postMessage({ t: 'setRemoteQueryResult', queryResult: model }); // Ensure all pre-downloaded artifacts are loaded into memory - await this.analysesResultsManager.loadDownloadedArtifacts(model.analysisSummaries); + await this.analysesResultsManager.loadDownloadedAnalyses(model.analysisSummaries); await this.setAnalysisResults(this.analysesResultsManager.getAnalysesResults(queryResult.queryId)); } @@ -66,7 +66,7 @@ export class RemoteQueriesInterfaceManager { * @param queryResult The result of the query. * @returns A fully created view model. */ - private async buildViewModel(query: RemoteQuery, queryResult: RemoteQueryResult): Promise { + private buildViewModel(query: RemoteQuery, queryResult: RemoteQueryResult): RemoteQueryResultViewModel { const queryFileName = path.basename(query.queryFilePath); const totalResultCount = queryResult.analysisSummaries.reduce((acc, cur) => acc + cur.resultCount, 0); const executionDuration = this.getDuration(queryResult.executionEndTime, query.executionStartTime); diff --git a/extensions/ql-vscode/src/vscode-tests/no-workspace/download-link.test.ts b/extensions/ql-vscode/src/vscode-tests/no-workspace/download-link.test.ts index c1262bf00..541c2070c 100644 --- a/extensions/ql-vscode/src/vscode-tests/no-workspace/download-link.test.ts +++ b/extensions/ql-vscode/src/vscode-tests/no-workspace/download-link.test.ts @@ -4,7 +4,7 @@ import * as path from 'path'; import { DownloadLink, createDownloadPath } from '../../remote-queries/download-link'; -describe('toDownloadPath', () => { +describe('createDownloadPath', () => { it('should return the correct path', () => { const downloadLink: DownloadLink = { id: 'abc', diff --git a/extensions/ql-vscode/src/vscode-tests/no-workspace/remote-query-history.test.ts b/extensions/ql-vscode/src/vscode-tests/no-workspace/remote-query-history.test.ts index b533fe576..19e032cd0 100644 --- a/extensions/ql-vscode/src/vscode-tests/no-workspace/remote-query-history.test.ts +++ b/extensions/ql-vscode/src/vscode-tests/no-workspace/remote-query-history.test.ts @@ -337,17 +337,18 @@ describe('Remote queries and query history manager', function() { // Load remoteQueryResult0.analysisSummaries[1] into memory await arm.downloadAnalysisResults(remoteQueryResult0.analysisSummaries[1], () => Promise.resolve()); - expect(await (arm as any).isAnalysisDownloadedNotInMemory(remoteQueryResult0.analysisSummaries[0])).to.be.true; + // on disk + expect(await (arm as any).isAnalysisDownloaded(remoteQueryResult0.analysisSummaries[0])).to.be.true; // in memory - expect(await (arm as any).isAnalysisDownloadedNotInMemory(remoteQueryResult0.analysisSummaries[1])).to.be.false; + expect(await (arm as any).isAnalysisDownloaded(remoteQueryResult0.analysisSummaries[1])).to.be.true; // not downloaded - expect(await (arm as any).isAnalysisDownloadedNotInMemory(remoteQueryResult0.analysisSummaries[2])).to.be.false; + expect(await (arm as any).isAnalysisDownloaded(remoteQueryResult0.analysisSummaries[2])).to.be.false; }); it('should load downloaded artifacts', async () => { - await arm.loadDownloadedArtifacts(remoteQueryResult0.analysisSummaries); + await arm.loadDownloadedAnalyses(remoteQueryResult0.analysisSummaries); const queryId = rawQueryHistory[0].queryId; const analysesResultsNwos = arm.getAnalysesResults(queryId).map(ar => ar.nwo).sort(); expect(analysesResultsNwos[0]).to.eq('github/vscode-codeql');