Skip to content

Commit d1c5f04

Browse files
Optimized the sha verification logic and test fixes
1 parent f85ef78 commit d1c5f04

2 files changed

Lines changed: 24 additions & 31 deletions

File tree

src/main/osinstaller/CxInstaller.ts

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ interface PlatformData {
2121
export class CxInstaller {
2222
private readonly platform: SupportedPlatforms;
2323
private cliVersion: string;
24-
private cliChecksum: string | null;
24+
private cliChecksum: string;
2525
private readonly resourceDirPath: string;
2626
private readonly installedCLIVersionFileName = 'cli-version';
2727
private readonly client: AstClient;
@@ -40,9 +40,9 @@ export class CxInstaller {
4040
}
4141

4242
// Returns the CLI version and its platform-specific SHA-256 checksum.
43-
// Reads from version and checksums files. Throws CxError if version is absent or version file is empty.
43+
// Throws CxError if the version or checksums file is missing, empty, or has no entry for the current platform.
4444
// Result is cached after the first read.
45-
async readASTCLIVersion(): Promise<{ version: string; checksum: string | null }> {
45+
async readASTCLIVersion(): Promise<{ version: string; checksum: string }> {
4646
if (this.cliVersion) {
4747
return { version: this.cliVersion, checksum: this.cliChecksum };
4848
}
@@ -51,29 +51,28 @@ export class CxInstaller {
5151
const architecture = this.getArchitecture();
5252
const key = `${platformData.platform}_${architecture}`;
5353

54-
let version: string | null = null;
54+
let version: string;
5555
try {
5656
const content = await fsPromises.readFile(this.getVersionFilePath(), 'utf-8');
5757
const trimmed = content.trim();
58-
if (trimmed) version = trimmed;
59-
} catch {
60-
// version file absent — will throw error below
61-
}
62-
63-
if (version === null) {
64-
throw new CxError(`CLI version not found`);
58+
if (!trimmed) throw new CxError('CLI version not found');
59+
version = trimmed;
60+
} catch (error) {
61+
if (error instanceof CxError) throw error;
62+
throw new CxError('CLI version not found');
6563
}
6664

67-
let checksum: string | null;
65+
let checksum: string;
6866
try {
6967
const content = await fsPromises.readFile(this.getChecksumsFilePath(), 'utf-8');
70-
checksum = (JSON.parse(content) as Record<string, string>)[key] ?? null;
71-
if (checksum === null) {
72-
logger.warn(`No checksum found for ${key} in checksums file. Download will not be verified.`);
68+
const parsed = (JSON.parse(content) as Record<string, string>);
69+
if (!parsed[key]) {
70+
throw new CxError(`No checksum found for ${key} in checksums file.`);
7371
}
74-
} catch {
75-
logger.warn(`Checksums file not found. Download of version ${version} will not be verified.`);
76-
checksum = null;
72+
checksum = parsed[key];
73+
} catch (error) {
74+
if (error instanceof CxError) throw error;
75+
throw new CxError(`Checksums file not found. Download of version ${version} will not be verified.`);
7776
}
7877

7978
this.cliVersion = version;

src/tests/CxInstallerTest.test.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { anyString, mock, instance, when, verify } from "ts-mockito";
33
import { AstClient } from "../main/client/AstClient";
44
import * as fs from "fs";
55
import * as crypto from "crypto";
6+
import * as path from "path";
67

78
// Mock AstClient and set up an instance from it
89
const astClientMock = mock(AstClient);
@@ -16,23 +17,23 @@ const cxInstallerWindows = new CxInstaller("win32", astClientInstance);
1617
describe("CxInstaller cases", () => {
1718
it('CxInstaller getDownloadURL Linux Successful case', async () => {
1819
const testVersion = '2.3.48';
19-
jest.spyOn(cxInstallerLinux as any, 'readASTCLIVersion').mockResolvedValue({ version: testVersion, checksum: null });
20+
jest.spyOn(cxInstallerLinux as any, 'readASTCLIVersion').mockResolvedValue({ version: testVersion, checksum: 'mock-checksum' });
2021
const { url } = await cxInstallerLinux.getDownloadURL();
2122
const architecture = getArchitecture(cxInstallerLinux.getPlatform());
2223
expect(url).toBe(`https://download.checkmarx.com/CxOne/CLI/${testVersion}/ast-cli_${testVersion}_linux_${architecture}.tar.gz`);
2324
});
2425

2526
it('CxInstaller getDownloadURL Mac Successful case', async () => {
2627
const testVersion = '2.3.48';
27-
jest.spyOn(cxInstallerMac as any, 'readASTCLIVersion').mockResolvedValue({ version: testVersion, checksum: null });
28+
jest.spyOn(cxInstallerMac as any, 'readASTCLIVersion').mockResolvedValue({ version: testVersion, checksum: 'mock-checksum' });
2829
const { url } = await cxInstallerMac.getDownloadURL();
2930
const architecture = getArchitecture(cxInstallerMac.getPlatform());
3031
expect(url).toBe(`https://download.checkmarx.com/CxOne/CLI/${testVersion}/ast-cli_${testVersion}_darwin_${architecture}.tar.gz`);
3132
});
3233

3334
it('CxInstaller getDownloadURL Windows Successful case', async () => {
3435
const testVersion = '2.3.48';
35-
jest.spyOn(cxInstallerWindows as any, 'readASTCLIVersion').mockResolvedValue({ version: testVersion, checksum: null });
36+
jest.spyOn(cxInstallerWindows as any, 'readASTCLIVersion').mockResolvedValue({ version: testVersion, checksum: 'mock-checksum' });
3637
const { url } = await cxInstallerWindows.getDownloadURL();
3738
const architecture = getArchitecture(cxInstallerWindows.getPlatform());
3839
expect(url).toBe(`https://download.checkmarx.com/CxOne/CLI/${testVersion}/ast-cli_${testVersion}_windows_${architecture}.zip`);
@@ -42,17 +43,17 @@ describe("CxInstaller cases", () => {
4243
describe("CxInstaller getExecutablePath cases", () => {
4344
it('CxInstaller getExecutablePath Linux Successful case', () => {
4445
const executablePath = cxInstallerLinux.getExecutablePath();
45-
expect(executablePath).toContain(`src/main/wrapper/resources/cx`);
46+
expect(executablePath).toContain(path.join('src', 'main', 'wrapper', 'resources', 'cx'));
4647
});
4748

4849
it('CxInstaller getExecutablePath Mac Successful case', () => {
4950
const executablePath = cxInstallerMac.getExecutablePath();
50-
expect(executablePath).toContain(`src/main/wrapper/resources/cx`);
51+
expect(executablePath).toContain(path.join('src', 'main', 'wrapper', 'resources', 'cx'));
5152
});
5253

5354
it('CxInstaller getExecutablePath Windows Successful case', () => {
5455
const executablePath = cxInstallerWindows.getExecutablePath();
55-
expect(executablePath).toContain(`src/main/wrapper/resources/cx.exe`);
56+
expect(executablePath).toContain(path.join('src', 'main', 'wrapper', 'resources', 'cx.exe'));
5657
});
5758
});
5859

@@ -143,13 +144,6 @@ describe("CxInstaller checksum verification cases", () => {
143144
expect(exitSpy).toHaveBeenCalledWith(1);
144145
});
145146

146-
it('CxInstaller null checksum skips verification', async () => {
147-
jest.spyOn(localLinux as any, 'readASTCLIVersion').mockResolvedValue({ version: '9.9.99', checksum: null });
148-
when(localMock.downloadFile(anyString(), anyString())).thenResolve();
149-
await localLinux.downloadIfNotInstalledCLI();
150-
expect(exitSpy).not.toHaveBeenCalled();
151-
});
152-
153147
it('CxInstaller CX_CLI_LOCATION skips checksum verification', async () => {
154148
process.env.CX_CLI_LOCATION = 'https://internal.example.com/cli';
155149
jest.spyOn(localLinux as any, 'readASTCLIVersion').mockResolvedValue({ version: '2.3.48', checksum: 'irrelevant' });

0 commit comments

Comments
 (0)