Skip to content

Commit c71a52d

Browse files
committed
[tests] Add a test for trivy.ts
1 parent e79ba88 commit c71a52d

File tree

1 file changed

+225
-0
lines changed

1 file changed

+225
-0
lines changed

__tests__/trivy.test.ts

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
import { Downloader, Trivy } from '../src/trivy';
2+
import { unlinkSync, writeFileSync } from 'fs';
3+
import { Vulnerability, TrivyOption } from '../src/interface';
4+
5+
const downloader = new Downloader();
6+
7+
function removeTrivyCmd(path: string) {
8+
path = path.replace(/\/trivy$/, '');
9+
if (downloader.trivyExists(path)) {
10+
unlinkSync(`${path}/trivy`);
11+
}
12+
}
13+
14+
describe('Platform', () => {
15+
test('is Liniux', () => {
16+
const result = downloader['checkPlatform']('linux');
17+
expect(result).toBe('Linux');
18+
});
19+
20+
test('is Darwin', () => {
21+
const result = downloader['checkPlatform']('darwin');
22+
expect(result).toBe('macOS');
23+
});
24+
25+
test('is not linux and darwin', () => {
26+
expect(() => {
27+
downloader['checkPlatform']('other');
28+
}).toThrowError('Sorry, other is not supported.');
29+
});
30+
});
31+
32+
describe('getDownloadUrl', () => {
33+
test('with latest version and linux', async () => {
34+
const version = 'latest';
35+
const os = 'Linux';
36+
const result = await downloader['getDownloadUrl'](version, os);
37+
expect(result).toMatch(
38+
/releases\/download\/v[0-9]\.[0-9]\.[0-9]\/trivy_[0-9]\.[0-9]\.[0-9]_Linux-64bit\.tar\.gz$/
39+
);
40+
});
41+
42+
test('with 0.2.0 and macOS', async () => {
43+
const version = '0.2.0';
44+
const os = 'macOS';
45+
const result = await downloader['getDownloadUrl'](version, os);
46+
expect(result).toMatch(
47+
/releases\/download\/v0\.2\.0\/trivy_0\.2\.0_macOS-64bit\.tar\.gz$/
48+
);
49+
});
50+
51+
test('with non-supported version', async () => {
52+
const version = 'none';
53+
const os = 'Linux';
54+
await expect(
55+
downloader['getDownloadUrl'](version, os)
56+
).rejects.toThrowError(
57+
'The Trivy version that you specified does not exist.'
58+
);
59+
});
60+
61+
test('with non-supported os', async () => {
62+
const version = 'latest';
63+
const os = 'none';
64+
await expect(
65+
downloader['getDownloadUrl'](version, os)
66+
).rejects.toThrowError(
67+
'Cloud not be found Trivy asset that You specified.'
68+
);
69+
});
70+
});
71+
72+
describe('Download trivy command', () => {
73+
afterAll(() => {
74+
removeTrivyCmd('__tests__');
75+
});
76+
77+
test('with valid download URL and save in __tests__', async () => {
78+
let downloadUrl = 'https://github.com/aquasecurity/trivy';
79+
downloadUrl += '/releases/download/v0.2.1/trivy_0.2.1_Linux-64bit.tar.gz';
80+
const savePath = './__tests__';
81+
await expect(
82+
downloader['downloadTrivyCmd'](downloadUrl, savePath)
83+
).resolves.toEqual(`${savePath}/trivy`);
84+
}, 300000);
85+
86+
test('with invalid download URL', async () => {
87+
const downloadUrl = 'https://github.com/this_is_invalid';
88+
await expect(downloader['downloadTrivyCmd'](downloadUrl)).rejects.toThrow();
89+
});
90+
});
91+
92+
describe('Trivy command', () => {
93+
beforeAll(() => {
94+
writeFileSync('./trivy', '');
95+
});
96+
97+
afterAll(() => {
98+
removeTrivyCmd('.');
99+
});
100+
101+
test('exists', () => {
102+
const result = downloader.trivyExists('.');
103+
expect(result).toBeTruthy();
104+
});
105+
106+
test('does not exist', () => {
107+
const result = downloader.trivyExists('src');
108+
expect(result).toBeFalsy();
109+
});
110+
});
111+
112+
describe('Scan', () => {
113+
let trivyPath: string;
114+
const image: string = 'alpine:3.10';
115+
116+
beforeAll(async () => {
117+
trivyPath = !downloader.trivyExists('./__tests__')
118+
? await downloader.download('latest', './__tests__')
119+
: './__tests__/trivy';
120+
}, 300000);
121+
122+
afterAll(() => {
123+
removeTrivyCmd(trivyPath);
124+
});
125+
126+
test('with valid options', () => {
127+
const options: TrivyOption = {
128+
severity: 'HIGH,CRITICAL',
129+
vulnType: 'os,library',
130+
ignoreUnfixed: true,
131+
};
132+
const result: Vulnerability[] = Trivy.scan(trivyPath, image, options);
133+
expect(result.length).toBeGreaterThanOrEqual(1);
134+
});
135+
136+
test('without ignoreUnfixed', () => {
137+
const options: TrivyOption = {
138+
severity: 'HIGH,CRITICAL',
139+
vulnType: 'os,library',
140+
ignoreUnfixed: false,
141+
};
142+
const result: Vulnerability[] = Trivy.scan(trivyPath, image, options);
143+
expect(result.length).toBeGreaterThanOrEqual(1);
144+
});
145+
146+
test('with invalid severity', () => {
147+
const invalidOption: TrivyOption = {
148+
severity: 'INVALID',
149+
vulnType: 'os,library',
150+
ignoreUnfixed: true,
151+
};
152+
expect(() => {
153+
Trivy.scan(trivyPath, image, invalidOption);
154+
}).toThrowError('severity option error: INVALID is unknown severity');
155+
});
156+
157+
test('with invalid vulnType', () => {
158+
const invalidOption: TrivyOption = {
159+
severity: 'HIGH',
160+
vulnType: 'INVALID',
161+
ignoreUnfixed: true,
162+
};
163+
expect(() => {
164+
Trivy.scan(trivyPath, image, invalidOption);
165+
}).toThrowError('vuln-type option error: INVALID is unknown vuln-type');
166+
});
167+
});
168+
169+
describe('Parse', () => {
170+
test('the result without vulnerabilities', () => {
171+
const vulnerabilities: Vulnerability[] = [
172+
{
173+
Target: 'alpine:3.10 (alpine 3.10.3)',
174+
Vulnerabilities: null,
175+
},
176+
];
177+
const result = Trivy.parse(vulnerabilities);
178+
expect(result).toBe('');
179+
});
180+
181+
test('the result including vulnerabilities', () => {
182+
const vulnerabilities: Vulnerability[] = [
183+
{
184+
Target: 'alpine:3.9 (alpine 3.9.4)',
185+
Vulnerabilities: [
186+
{
187+
VulnerabilityID: 'CVE-2019-14697',
188+
PkgName: 'musl',
189+
InstalledVersion: '1.1.20-r4',
190+
FixedVersion: '1.1.20-r5',
191+
Description:
192+
"musl libc through 1.1.23 has an x87 floating-point stack adjustment imbalance, related to the math/i386/ directory. In some cases, use of this library could introduce out-of-bounds writes that are not present in an application's source code.",
193+
Severity: 'HIGH',
194+
References: [
195+
'http://www.openwall.com/lists/oss-security/2019/08/06/4',
196+
'https://www.openwall.com/lists/musl/2019/08/06/1',
197+
],
198+
},
199+
{
200+
VulnerabilityID: 'CVE-2019-1549',
201+
PkgName: 'openssl',
202+
InstalledVersion: '1.1.1b-r1',
203+
FixedVersion: '1.1.1d-r0',
204+
Title: 'openssl: information disclosure in fork()',
205+
Description:
206+
'OpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c).',
207+
Severity: 'MEDIUM',
208+
References: [
209+
'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1549',
210+
'https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=1b0fe00e2704b5e20334a16d3c9099d1ba2ef1be',
211+
'https://lists.fedoraproject.org/archives/list/[email protected]/message/GY6SNRJP2S7Y42GIIDO3HXPNMDYN2U3A/',
212+
'https://security.netapp.com/advisory/ntap-20190919-0002/',
213+
'https://support.f5.com/csp/article/K44070243',
214+
'https://www.openssl.org/news/secadv/20190910.txt',
215+
],
216+
},
217+
],
218+
},
219+
];
220+
const result = Trivy.parse(vulnerabilities);
221+
expect(result).toMatch(
222+
/\|Title\|Severity\|CVE\|Package Name\|Installed Version\|Fixed Version\|References\|/
223+
);
224+
});
225+
});

0 commit comments

Comments
 (0)