Skip to content

Commit 6ba0cc4

Browse files
committed
test: system test
introducing a new system test infrastructure to the Kubernetes Monitor. this kind of tests focus on the Kubernetes-Monitor's code, and its interactions with Kubernetes, without letting it run completely in an end-to-end fashion. this means that: 1. we're losing the Monitor's "natural" runtime environment (inside the cluster) 2. we're gaining the ability to test for implementation details we otherwise couldn'tsuch as the content of the payload the Kubernetes Monitor sends out (as opposed to testing its affect on an external upstream) the new test creates a KinD cluster, but runs the Kubernetes-Monitor _locally_ (not from inside the cluster). it uses Nock to assert outgoing requests. right now it only uses a java deployment, because it's distroless, saving us the trouble of forcing an OS on Skopeo's pull (which would try to get an Ubuntu image for MacOS... and fail.)
1 parent f602ec9 commit 6ba0cc4

File tree

4 files changed

+152
-0
lines changed

4 files changed

+152
-0
lines changed

package-lock.json

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"@typescript-eslint/parser": "^2.6.1",
5252
"eslint": "^6.6.0",
5353
"eslint-config-prettier": "^6.5.0",
54+
"nock": "^11.7.2",
5455
"sinon": "^8.0.1",
5556
"tap": "^14.10.5",
5657
"ts-node": "^8.1.0",

test/fixtures/java-deployment.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: java
5+
namespace: services
6+
labels:
7+
app.kubernetes.io/name: java
8+
spec:
9+
replicas: 2
10+
selector:
11+
matchLabels:
12+
app.kubernetes.io/name: java
13+
template:
14+
metadata:
15+
labels:
16+
app.kubernetes.io/name: java
17+
spec:
18+
containers:
19+
- image: java:latest
20+
imagePullPolicy: Always
21+
name: java
22+
securityContext: {}

test/system/kind.test.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import * as tap from 'tap';
2+
import * as nock from 'nock';
3+
import * as sleep from 'sleep-promise';
4+
import { exec } from 'child-process-promise';
5+
6+
import * as kubectl from '../helpers/kubectl';
7+
import * as kind from '../setup/platforms/kind';
8+
9+
// let integrationId: string;
10+
11+
async function tearDown() {
12+
console.log('Begin removing the snyk-monitor...');
13+
await kind.deleteCluster();
14+
console.log('Removed the snyk-monitor!');
15+
}
16+
17+
tap.tearDown(tearDown);
18+
19+
tap.test('Kubernetes-Monitor with KinD', async (t) => {
20+
21+
// Start fresh
22+
try {
23+
await tearDown();
24+
} catch (error) {
25+
console.log(`could not start with a clean environment: ${error.message}`);
26+
}
27+
28+
// install Skopeo
29+
// TODO: this thing should probably be in a setup test environment script
30+
// not in this file
31+
try {
32+
await exec('which skopeo');
33+
console.log('Skopeo already installed :tada:');
34+
} catch (err) {
35+
// linux-oriented, not mac
36+
// for mac, install skopeo with brew
37+
console.log('installing Skopeo');
38+
await exec('git clone https://github.com/containers/skopeo');
39+
await exec('(cd skopeo && make binary-static DISABLE_CGO=1)');
40+
await exec('sudo mkdir -p /etc/containers');
41+
await exec('sudo chown circleci:circleci /etc/containers');
42+
await exec('cp ./skopeo/default-policy.json /etc/containers/policy.json');
43+
44+
process.env['PATH'] = process.env['PATH'] + ':./skopeo';
45+
}
46+
47+
// kubectl
48+
await kubectl.downloadKubectl();
49+
50+
// KinD
51+
await kind.createCluster();
52+
await kind.exportKubeConfig();
53+
Promise.all([
54+
kubectl.createNamespace('snyk-monitor'),
55+
kubectl.createNamespace('services'),
56+
]);
57+
// wait for default service account
58+
await kubectl.waitForServiceAccount('default', 'default');
59+
60+
// Services
61+
await Promise.all([
62+
kubectl.applyK8sYaml('./test/fixtures/java-deployment.yaml'),
63+
]);
64+
65+
// TODO: wait for the services to start?
66+
67+
// Setup nocks
68+
nock('https://kubernetes-upstream.snyk.io')
69+
.post('/api/v1/workload')
70+
.times(1)
71+
.reply(200, (uri, requestBody) => {
72+
// TODO assert POST payload
73+
});
74+
75+
nock('https://kubernetes-upstream.snyk.io')
76+
.post('/api/v1/dependency-graph')
77+
.times(1)
78+
.reply(200, (uri, requestBody) => {
79+
// TODO assert POST payload
80+
});
81+
82+
// Start the monitor
83+
require('../../src');
84+
85+
// TODO: replace with being event driven?
86+
// will still need SOME timeout
87+
while (true) {
88+
if (nock.isDone()) {
89+
break;
90+
} else {
91+
await sleep(5 * 1000);
92+
}
93+
}
94+
95+
// additional asserts?
96+
t.ok(nock.isDone(), 'all outgoing calls were made');
97+
98+
// TODO cleanup the images we saved to /var/tmp?
99+
});

0 commit comments

Comments
 (0)