Pass variantAnalysisStorageLocation to the results manager

This commit is contained in:
shati-patel
2022-10-19 15:25:11 +01:00
parent 6b7ebf543c
commit 43de90f03d
3 changed files with 38 additions and 28 deletions

View File

@@ -1,3 +1,5 @@
import * as path from 'path';
import * as ghApiClient from './gh-api/gh-api-client'; import * as ghApiClient from './gh-api/gh-api-client';
import { CancellationToken, commands, EventEmitter, ExtensionContext, window } from 'vscode'; import { CancellationToken, commands, EventEmitter, ExtensionContext, window } from 'vscode';
import { DisposableObject } from '../pure/disposable-object'; import { DisposableObject } from '../pure/disposable-object';
@@ -39,14 +41,14 @@ export class VariantAnalysisManager extends DisposableObject implements VariantA
constructor( constructor(
private readonly ctx: ExtensionContext, private readonly ctx: ExtensionContext,
cliServer: CodeQLCliServer, cliServer: CodeQLCliServer,
storagePath: string, private readonly storagePath: string,
logger: Logger, logger: Logger,
) { ) {
super(); super();
this.variantAnalysisMonitor = this.push(new VariantAnalysisMonitor(ctx)); this.variantAnalysisMonitor = this.push(new VariantAnalysisMonitor(ctx));
this.variantAnalysisMonitor.onVariantAnalysisChange(this.onVariantAnalysisUpdated.bind(this)); this.variantAnalysisMonitor.onVariantAnalysisChange(this.onVariantAnalysisUpdated.bind(this));
this.variantAnalysisResultsManager = this.push(new VariantAnalysisResultsManager(cliServer, storagePath, logger)); this.variantAnalysisResultsManager = this.push(new VariantAnalysisResultsManager(cliServer, logger));
this.variantAnalysisResultsManager.onResultLoaded(this.onRepoResultLoaded.bind(this)); this.variantAnalysisResultsManager.onResultLoaded(this.onRepoResultLoaded.bind(this));
} }
@@ -87,7 +89,7 @@ export class VariantAnalysisManager extends DisposableObject implements VariantA
throw new Error(`No variant analysis with id: ${variantAnalysisId}`); throw new Error(`No variant analysis with id: ${variantAnalysisId}`);
} }
await this.variantAnalysisResultsManager.loadResults(variantAnalysisId, repositoryFullName); await this.variantAnalysisResultsManager.loadResults(variantAnalysisId, this.getVariantAnalysisStorageLocation(variantAnalysisId), repositoryFullName);
} }
private async onVariantAnalysisUpdated(variantAnalysis: VariantAnalysis | undefined): Promise<void> { private async onVariantAnalysisUpdated(variantAnalysis: VariantAnalysis | undefined): Promise<void> {
@@ -160,7 +162,7 @@ export class VariantAnalysisManager extends DisposableObject implements VariantA
repoState.downloadStatus = VariantAnalysisScannedRepositoryDownloadStatus.InProgress; repoState.downloadStatus = VariantAnalysisScannedRepositoryDownloadStatus.InProgress;
await this.onRepoStateUpdated(variantAnalysisSummary.id, repoState); await this.onRepoStateUpdated(variantAnalysisSummary.id, repoState);
await this.variantAnalysisResultsManager.download(credentials, variantAnalysisSummary.id, repoTask); await this.variantAnalysisResultsManager.download(credentials, variantAnalysisSummary.id, repoTask, this.getVariantAnalysisStorageLocation(variantAnalysisSummary.id));
} }
repoState.downloadStatus = VariantAnalysisScannedRepositoryDownloadStatus.Succeeded; repoState.downloadStatus = VariantAnalysisScannedRepositoryDownloadStatus.Succeeded;
@@ -180,7 +182,10 @@ export class VariantAnalysisManager extends DisposableObject implements VariantA
} }
public getVariantAnalysisStorageLocation(variantAnalysisId: number): string { public getVariantAnalysisStorageLocation(variantAnalysisId: number): string {
return this.variantAnalysisResultsManager.getStorageDirectory(variantAnalysisId); return path.join(
this.storagePath,
`${variantAnalysisId}`
);
} }
/** /**

View File

@@ -39,7 +39,6 @@ export class VariantAnalysisResultsManager extends DisposableObject {
constructor( constructor(
private readonly cliServer: CodeQLCliServer, private readonly cliServer: CodeQLCliServer,
private readonly storagePath: string,
private readonly logger: Logger, private readonly logger: Logger,
) { ) {
super(); super();
@@ -50,12 +49,13 @@ export class VariantAnalysisResultsManager extends DisposableObject {
credentials: Credentials, credentials: Credentials,
variantAnalysisId: number, variantAnalysisId: number,
repoTask: VariantAnalysisRepoTask, repoTask: VariantAnalysisRepoTask,
variantAnalysisStoragePath: string,
): Promise<void> { ): Promise<void> {
if (!repoTask.artifact_url) { if (!repoTask.artifact_url) {
throw new Error('Missing artifact URL'); throw new Error('Missing artifact URL');
} }
const resultDirectory = this.getRepoStorageDirectory(variantAnalysisId, repoTask.repository.full_name); const resultDirectory = this.getRepoStorageDirectory(variantAnalysisStoragePath, repoTask.repository.full_name);
const result = await ghApiClient.getVariantAnalysisRepoResult( const result = await ghApiClient.getVariantAnalysisRepoResult(
credentials, credentials,
@@ -82,18 +82,20 @@ export class VariantAnalysisResultsManager extends DisposableObject {
public async loadResults( public async loadResults(
variantAnalysisId: number, variantAnalysisId: number,
variantAnalysisStoragePath: string,
repositoryFullName: string repositoryFullName: string
): Promise<VariantAnalysisScannedRepositoryResult> { ): Promise<VariantAnalysisScannedRepositoryResult> {
const result = this.cachedResults.get(createCacheKey(variantAnalysisId, repositoryFullName)); const result = this.cachedResults.get(createCacheKey(variantAnalysisId, repositoryFullName));
return result ?? await this.loadResultsIntoMemory(variantAnalysisId, repositoryFullName); return result ?? await this.loadResultsIntoMemory(variantAnalysisId, variantAnalysisStoragePath, repositoryFullName);
} }
private async loadResultsIntoMemory( private async loadResultsIntoMemory(
variantAnalysisId: number, variantAnalysisId: number,
variantAnalysisStoragePath: string,
repositoryFullName: string, repositoryFullName: string,
): Promise<VariantAnalysisScannedRepositoryResult> { ): Promise<VariantAnalysisScannedRepositoryResult> {
const result = await this.loadResultsFromStorage(variantAnalysisId, repositoryFullName); const result = await this.loadResultsFromStorage(variantAnalysisId, variantAnalysisStoragePath, repositoryFullName);
this.cachedResults.set(createCacheKey(variantAnalysisId, repositoryFullName), result); this.cachedResults.set(createCacheKey(variantAnalysisId, repositoryFullName), result);
this._onResultLoaded.fire(result); this._onResultLoaded.fire(result);
return result; return result;
@@ -101,13 +103,14 @@ export class VariantAnalysisResultsManager extends DisposableObject {
private async loadResultsFromStorage( private async loadResultsFromStorage(
variantAnalysisId: number, variantAnalysisId: number,
variantAnalysisStoragePath: string,
repositoryFullName: string, repositoryFullName: string,
): Promise<VariantAnalysisScannedRepositoryResult> { ): Promise<VariantAnalysisScannedRepositoryResult> {
if (!(await this.isVariantAnalysisRepoDownloaded(variantAnalysisId, repositoryFullName))) { if (!(await this.isVariantAnalysisRepoDownloaded(variantAnalysisStoragePath, repositoryFullName))) {
throw new Error('Variant analysis results not downloaded'); throw new Error('Variant analysis results not downloaded');
} }
const storageDirectory = this.getRepoStorageDirectory(variantAnalysisId, repositoryFullName); const storageDirectory = this.getRepoStorageDirectory(variantAnalysisStoragePath, repositoryFullName);
const repoTask: VariantAnalysisRepoTask = await fs.readJson(path.join(storageDirectory, VariantAnalysisResultsManager.REPO_TASK_FILENAME)); const repoTask: VariantAnalysisRepoTask = await fs.readJson(path.join(storageDirectory, VariantAnalysisResultsManager.REPO_TASK_FILENAME));
@@ -144,10 +147,10 @@ export class VariantAnalysisResultsManager extends DisposableObject {
} }
private async isVariantAnalysisRepoDownloaded( private async isVariantAnalysisRepoDownloaded(
variantAnalysisId: number, variantAnalysisStoragePath: string,
repositoryFullName: string, repositoryFullName: string,
): Promise<boolean> { ): Promise<boolean> {
return await fs.pathExists(this.getRepoStorageDirectory(variantAnalysisId, repositoryFullName)); return await fs.pathExists(this.getRepoStorageDirectory(variantAnalysisStoragePath, repositoryFullName));
} }
private async readBqrsResults(filePath: string, fileLinkPrefix: string, sourceLocationPrefix: string): Promise<AnalysisRawResults> { private async readBqrsResults(filePath: string, fileLinkPrefix: string, sourceLocationPrefix: string): Promise<AnalysisRawResults> {
@@ -165,16 +168,9 @@ export class VariantAnalysisResultsManager extends DisposableObject {
return processedSarif.alerts; return processedSarif.alerts;
} }
public getStorageDirectory(variantAnalysisId: number): string { public getRepoStorageDirectory(variantAnalysisStoragePath: string, fullName: string): string {
return path.join( return path.join(
this.storagePath, variantAnalysisStoragePath,
`${variantAnalysisId}`
);
}
public getRepoStorageDirectory(variantAnalysisId: number, fullName: string): string {
return path.join(
this.getStorageDirectory(variantAnalysisId),
fullName fullName
); );
} }

View File

@@ -33,7 +33,7 @@ describe(VariantAnalysisResultsManager.name, () => {
try { try {
const extension = await extensions.getExtension<CodeQLExtensionInterface | Record<string, never>>('GitHub.vscode-codeql')!.activate(); const extension = await extensions.getExtension<CodeQLExtensionInterface | Record<string, never>>('GitHub.vscode-codeql')!.activate();
cli = extension.cliServer; cli = extension.cliServer;
variantAnalysisResultsManager = new VariantAnalysisResultsManager(cli, storagePath, logger); variantAnalysisResultsManager = new VariantAnalysisResultsManager(cli, logger);
} catch (e) { } catch (e) {
fail(e as Error); fail(e as Error);
} }
@@ -45,12 +45,17 @@ describe(VariantAnalysisResultsManager.name, () => {
describe('download', () => { describe('download', () => {
let getOctokitStub: sinon.SinonStub; let getOctokitStub: sinon.SinonStub;
let variantAnalysisStoragePath: string;
const mockCredentials = { const mockCredentials = {
getOctokit: () => Promise.resolve({ getOctokit: () => Promise.resolve({
request: getOctokitStub request: getOctokitStub
}) })
} as unknown as Credentials; } as unknown as Credentials;
beforeEach(async () => {
variantAnalysisStoragePath = path.join(storagePath, variantAnalysisId.toString());
});
describe('when the artifact_url is missing', async () => { describe('when the artifact_url is missing', async () => {
it('should not try to download the result', async () => { it('should not try to download the result', async () => {
const dummyRepoTask = createMockVariantAnalysisRepoTask(); const dummyRepoTask = createMockVariantAnalysisRepoTask();
@@ -60,7 +65,8 @@ describe(VariantAnalysisResultsManager.name, () => {
await variantAnalysisResultsManager.download( await variantAnalysisResultsManager.download(
mockCredentials, mockCredentials,
variantAnalysisId, variantAnalysisId,
dummyRepoTask dummyRepoTask,
variantAnalysisStoragePath
); );
expect.fail('Expected an error to be thrown'); expect.fail('Expected an error to be thrown');
@@ -78,7 +84,7 @@ describe(VariantAnalysisResultsManager.name, () => {
beforeEach(async () => { beforeEach(async () => {
dummyRepoTask = createMockVariantAnalysisRepoTask(); dummyRepoTask = createMockVariantAnalysisRepoTask();
storageDirectory = variantAnalysisResultsManager.getRepoStorageDirectory(variantAnalysisId, dummyRepoTask.repository.full_name); storageDirectory = variantAnalysisResultsManager.getRepoStorageDirectory(variantAnalysisStoragePath, dummyRepoTask.repository.full_name);
const sourceFilePath = path.join(__dirname, '../../../../src/vscode-tests/cli-integration/data/variant-analysis-results.zip'); const sourceFilePath = path.join(__dirname, '../../../../src/vscode-tests/cli-integration/data/variant-analysis-results.zip');
arrayBuffer = fs.readFileSync(sourceFilePath).buffer; arrayBuffer = fs.readFileSync(sourceFilePath).buffer;
@@ -97,7 +103,8 @@ describe(VariantAnalysisResultsManager.name, () => {
await variantAnalysisResultsManager.download( await variantAnalysisResultsManager.download(
mockCredentials, mockCredentials,
variantAnalysisId, variantAnalysisId,
dummyRepoTask dummyRepoTask,
variantAnalysisStoragePath
); );
expect(getVariantAnalysisRepoResultStub.calledOnce).to.be.true; expect(getVariantAnalysisRepoResultStub.calledOnce).to.be.true;
@@ -107,7 +114,8 @@ describe(VariantAnalysisResultsManager.name, () => {
await variantAnalysisResultsManager.download( await variantAnalysisResultsManager.download(
mockCredentials, mockCredentials,
variantAnalysisId, variantAnalysisId,
dummyRepoTask dummyRepoTask,
variantAnalysisStoragePath
); );
expect(fs.existsSync(`${storageDirectory}/results.zip`)).to.be.true; expect(fs.existsSync(`${storageDirectory}/results.zip`)).to.be.true;
@@ -117,7 +125,8 @@ describe(VariantAnalysisResultsManager.name, () => {
await variantAnalysisResultsManager.download( await variantAnalysisResultsManager.download(
mockCredentials, mockCredentials,
variantAnalysisId, variantAnalysisId,
dummyRepoTask dummyRepoTask,
variantAnalysisStoragePath
); );
expect(fs.existsSync(`${storageDirectory}/results/results.sarif`)).to.be.true; expect(fs.existsSync(`${storageDirectory}/results/results.sarif`)).to.be.true;