Skip to content

Commit 6474b54

Browse files
authored
Merge pull request #693 from snyk/chore/tap-to-jest
chore: move some tap tests to jest
2 parents fe485bd + 26b3d3d commit 6474b54

20 files changed

+1031
-1027
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
"scripts": {
1313
"pretest": "./scripts/docker/build-image.sh",
1414
"test": "npm run lint && npm run build && npm run test:unit:tap && npm run test:unit:jest && npm run test:integration:kind:helm",
15-
"test:unit:tap": "NODE_ENV=test tap test/unit/*.test.ts test/unit/**/*.test.ts --timeout=300",
16-
"test:unit:jest": "jest --logHeapUsage --ci test/unit",
15+
"test:unit:tap": "NODE_ENV=test tap test/unit/**/*.test.ts --timeout=300",
16+
"test:unit:jest": "jest --logHeapUsage --ci --bail --forceExit test/unit",
1717
"test:system": "jest --logHeapUsage --ci --maxWorkers=1 test/system",
1818
"test:integration:kind:yaml": "DEPLOYMENT_TYPE=YAML TEST_PLATFORM=kind CREATE_CLUSTER=true jest --logHeapUsage --ci --maxWorkers=1 test/integration/kubernetes.spec.ts",
1919
"test:integration:kind:helm": "DEPLOYMENT_TYPE=Helm TEST_PLATFORM=kind CREATE_CLUSTER=true jest --logHeapUsage --ci --maxWorkers=1 test/integration/kubernetes.spec.ts",

test/helpers/deployment.ts

Lines changed: 0 additions & 114 deletions
This file was deleted.

test/unit/deployment-files.spec.ts

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { parse } from 'yaml';
2+
import { readFileSync } from 'fs';
3+
import { V1Deployment } from '@kubernetes/client-node';
4+
import { config } from '../../src/common/config';
5+
6+
/**
7+
* Note that these checks are also performed at runtime on the deployed snyk-monitor, see the integration tests.
8+
*/
9+
10+
describe('deployment files tests', () => {
11+
test.concurrent(
12+
'ensure the security properties of the deployment files are unchanged',
13+
async () => {
14+
expect(config.IMAGE_STORAGE_ROOT).toEqual('/var/tmp');
15+
16+
const deploymentFiles = ['./snyk-monitor-deployment.yaml'];
17+
18+
for (const filePath of deploymentFiles) {
19+
const fileContent = readFileSync(filePath, 'utf8');
20+
const deployment: V1Deployment = parse(fileContent);
21+
22+
validateSecureConfiguration(deployment);
23+
validateVolumeMounts(deployment);
24+
validateEnvironmentVariables(deployment);
25+
}
26+
},
27+
);
28+
});
29+
30+
export function validateEnvironmentVariables(deployment: V1Deployment) {
31+
if (
32+
!deployment.spec ||
33+
!deployment.spec.template.spec ||
34+
!deployment.spec.template.spec.containers ||
35+
deployment.spec.template.spec.containers.length === 0 ||
36+
!deployment.spec.template.spec.containers[0].env
37+
) {
38+
fail('bad container spec or missing env');
39+
}
40+
41+
const env = deployment.spec.template.spec.containers[0].env;
42+
43+
const envHasHomeEntry = env.some(
44+
(entry) => entry.name === 'HOME' && entry.value === '/srv/app',
45+
);
46+
expect(envHasHomeEntry).toBeTruthy();
47+
}
48+
49+
export function validateSecureConfiguration(deployment: V1Deployment) {
50+
if (
51+
!deployment.spec ||
52+
!deployment.spec.template.spec ||
53+
!deployment.spec.template.spec.containers ||
54+
deployment.spec.template.spec.containers.length === 0 ||
55+
!deployment.spec.template.spec.containers[0].securityContext
56+
) {
57+
fail('bad container spec or missing securityContext');
58+
}
59+
60+
const securityContext =
61+
deployment.spec.template.spec.containers[0].securityContext;
62+
63+
if (!securityContext.capabilities) {
64+
fail('missing capabilities section in pod securityContext');
65+
}
66+
67+
expect(securityContext.capabilities.drop).toEqual(['ALL']);
68+
69+
if (securityContext.capabilities.add) {
70+
expect(securityContext.capabilities.add.includes('SYS_ADMIN')).toEqual(
71+
false,
72+
);
73+
}
74+
75+
expect(securityContext.readOnlyRootFilesystem).toEqual(true);
76+
77+
expect(securityContext.allowPrivilegeEscalation).toEqual(false);
78+
expect(securityContext.privileged).toEqual(false);
79+
expect(securityContext.runAsNonRoot).toEqual(true);
80+
}
81+
82+
export function validateVolumeMounts(deployment: V1Deployment) {
83+
if (
84+
!deployment.spec ||
85+
!deployment.spec.template.spec ||
86+
!deployment.spec.template.spec.containers ||
87+
deployment.spec.template.spec.containers.length === 0 ||
88+
!deployment.spec.template.spec.containers[0].volumeMounts
89+
) {
90+
fail('bad container spec or missing volumeMounts');
91+
}
92+
93+
const volumeMounts = deployment.spec.template.spec.containers[0].volumeMounts;
94+
95+
const temporaryStorageMount = volumeMounts.find(
96+
(mount) => mount.name === 'temporary-storage',
97+
);
98+
if (!temporaryStorageMount) {
99+
fail('missing deployment mount "temporary-storage"');
100+
}
101+
102+
expect(temporaryStorageMount.mountPath).toEqual('/var/tmp');
103+
104+
const dockerConfigMount = volumeMounts.find(
105+
(mount) => mount.name === 'docker-config',
106+
);
107+
if (!dockerConfigMount) {
108+
fail('missing deployment mount "docker-config"');
109+
}
110+
111+
expect(dockerConfigMount.readOnly).toEqual(true);
112+
expect(dockerConfigMount.mountPath).toEqual('/srv/app/.docker');
113+
}

test/unit/deployment-files.test.ts

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import * as credentials from '../../../src/scanner/images/credentials';
2+
3+
describe('ECR image parsing tests', () => {
4+
test.concurrent('ecrRegionFromFullImageName()', async () => {
5+
const imageFullNameTemplate = 'aws_account_id.dkr.ecr.region.amazonaws.com/my-web-app:latest';
6+
const ecrRegionTemplate = credentials.ecrRegionFromFullImageName(imageFullNameTemplate);
7+
expect(ecrRegionTemplate).toEqual('region');
8+
9+
const imageFullName = '291964488713.dkr.ecr.us-east-2.amazonaws.com/snyk/debian:10';
10+
const ecrRegion = credentials.ecrRegionFromFullImageName(imageFullName);
11+
expect(ecrRegion).toEqual('us-east-2');
12+
13+
expect(() => {credentials.ecrRegionFromFullImageName('');}).toThrow();
14+
expect(() => {credentials.ecrRegionFromFullImageName('dkr.ecr.region.amazonaws.com/my-web-app:latest');}).toThrow();
15+
expect(() => {credentials.ecrRegionFromFullImageName('aws_account_id.dkr.ecr.amazonaws.com/my-web-app:latest');}).toThrow();
16+
expect(() => {credentials.ecrRegionFromFullImageName('aws_account_id.dkr.ecr.region.amazonaws.com');}).toThrow();
17+
});
18+
19+
test.concurrent('isEcrSource()', async () => {
20+
const sourceCredentialsForRandomImageName = credentials.isEcrSource('derka');
21+
expect(sourceCredentialsForRandomImageName).toEqual(false);
22+
23+
const sourceCredentialsForInvalidEcrImage = credentials.isEcrSource('derka.ecr.derka');
24+
expect(sourceCredentialsForInvalidEcrImage).toEqual(false);
25+
26+
const sourceCredentialsForEcrImage = credentials.isEcrSource('aws_account_id.dkr.ecr.region.amazonaws.com/my-web-app:latest');
27+
expect(sourceCredentialsForEcrImage).toEqual(true);
28+
29+
const sourceCredentialsForEcrImageWithRepo = credentials.isEcrSource('a291964488713.dkr.ecr.us-east-2.amazonaws.com/snyk/debian:10');
30+
expect(sourceCredentialsForEcrImageWithRepo).toEqual(true);
31+
32+
const sourceCredentialsForEcrImageMixedCase = credentials.isEcrSource('aws_account_id.dKr.ecR.region.amazonAWS.cOm/my-web-app:latest');
33+
expect(sourceCredentialsForEcrImageMixedCase).toEqual(true);
34+
});
35+
});

test/unit/scanner/image-registry-credentials.test.ts

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)