Skip to content

Commit

Permalink
Fix E2E Test (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
bryopsida authored Sep 30, 2022
1 parent dde9c4f commit 765045c
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 71 deletions.
18 changes: 13 additions & 5 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ jobs:
strategy:
fail-fast: false
matrix:
k8s-version: [1.22.13, 1.23.10, 1.24.4, 1.25.0]
k8s-version: [1.22, 1.23, 1.24, 1.25]
needs:
- build-image
env:
Expand All @@ -138,8 +138,15 @@ jobs:
cache: 'npm'
- name: Install Dependencies
run: npm ci
- name: Start Minikube
run: npm run minikube:start -- --kubernetes-version=${{ matrix.k8s-version }}
- name: Spin Up MicroK8S
run: |
sudo snap install microk8s --classic --channel=${{ matrix.k8s-version }}/stable
sudo microk8s enable dns storage rbac ingress
sudo microk8s status --wait-ready
sudo microk8s kubectl rollout status deployment/hostpath-provisioner -n kube-system
mkdir -p ~/.kube
sudo microk8s config > ~/.kube/config
sudo snap install kubectl --classic
- name: Create Pull Secret
run: npm run k8s:createPullSecret --helm_namespace=default --registry_username=${{ github.actor }} --registry_password=${{ github.token }}
- name: Add Helm Repos
Expand All @@ -159,16 +166,17 @@ jobs:
if: ${{ failure() }}
run: |
mkdir -p /tmp/failure-logs
minikube logs > /tmp/failure-logs/minikube.log
kubectl logs deployments/k8s-jacoco-operator --prefix=true --ignore-errors=true --timestamps --pod-running-timeout=60s > /tmp/failure-logs/k8s-jacoco-operator.deployment.log
kubectl describe deployment k8s-jacoco-operator > /tmp/failure-logs/k8s-jacoco-operator.deployment.describe
kubectl get deployment k8s-jacoco-operator -o yaml > /tmp/failure-logs/k8s-jacoco-operator.deployment.yaml
kubectl describe configmap k8s-jacoco-operator > /tmp/failure-logs/k8s-jacoco-operator.configmap.describe
inspectTarball=$(sudo microk8s inspect | grep -Po "/var/snap/microk8s/.*\.tar\.gz")
sudo cp $inspectTarball /tmp/failure-logs/
- name: Upload Logs On Failure
if: ${{ failure() }}
uses: actions/upload-artifact@v3
with:
name: ${{ runner.name }} minikube logs
name: ${{ runner.name }} microk8s logs
path: |
/tmp/failure-logs
publish-chart:
Expand Down
74 changes: 23 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,7 @@
# k8s-jacoco-operator
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=curium-rocks_k8s-jacoco-operator&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=curium-rocks_k8s-jacoco-operator) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=curium-rocks_k8s-jacoco-operator&metric=coverage)](https://sonarcloud.io/summary/new_code?id=curium-rocks_k8s-jacoco-operator) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=curium-rocks_k8s-jacoco-operator&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=curium-rocks_k8s-jacoco-operator) [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=curium-rocks_k8s-jacoco-operator&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=curium-rocks_k8s-jacoco-operator) [![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=curium-rocks_k8s-jacoco-operator&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=curium-rocks_k8s-jacoco-operator) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=curium-rocks_k8s-jacoco-operator&metric=bugs)](https://sonarcloud.io/summary/new_code?id=curium-rocks_k8s-jacoco-operator)

This template provides a kick start to making a kubernetes admission controller using TypeScript and Node.JS, uses a Mutating Webhook.
- [Kubernetes-client/client-node](https://github.com/kubernetes-client/javascript)
- [Jest](https://github.com/facebook/jest)
- [Github Action CI](.github/workflows/ci.yaml)
- [Renovate](https://github.com/renovatebot/renovate)
- [Eslint (with standard config)](https://github.com/standard/eslint-config-standard)
- [Typescript](https://github.com/Microsoft/TypeScript)
- [Config](https://github.com/node-config/node-config)
- [Pino](https://github.com/pinojs/pino)
- [Fastify](https://github.com/fastify/fastify)
- [Fast Json Patch](https://github.com/Starcounter-Jack/JSON-Patch)
- [InversifyJS](https://github.com/inversify/InversifyJS)
- [Sonar Project File](./sonar-project.properties)
- [Dockerfile](./Dockerfile)


## NPM Scripts
The following scripts are included in the NPM project configuration
- `lint` lints the source code using eslint
- `lint:fix` automatically fixes any lint errors that can be fixed automatically
- `test` uses jest to run test suites
- `test:e2e` runs e2e test suite, this requires an active helm:deploy
- `build` compiles the typescript into js and places it in the `dist` folder
- `build:image` builds the container image
- `minikube:start` create a minikube k8s cluster
- `minikube:stop` stop minikube but do not delete
- `minikube:delete` delete the minikube cluster
- `helm:addRepos` adds helm repos
- `helm:deployCertManager` deploy cert-manager for TLS
- `helm:deploy` deploy the app to k8s using helm
- `helm:template` print the k8s yaml that would be applied to k8s when using `helm:deploy`
- `helm:uninstall` remove the app from k8s
- `helm:uninstallCertManager` remove cert-manager from the k8s cluster
A operator that injects the jacoco agent into pods so you can collect coverage data when running tests against Java services deployed in kubernetes.

## Deploy it
If you don't already have cert manager installed you will need to run:
Expand All @@ -50,27 +18,31 @@ Verify it worked `helm search repo k8s` and you should see something like.

```
NAME CHART VERSION APP VERSION DESCRIPTION
k8s/k8s-jacoco-operator... 0.1.0 0.1.0 A starter template for a dynamic admission mut...
k8s/k8s-jacoco-operator... 0.1.0 0.1.0 ......
```

Deploy the app `helm upgrade --install starter k8s/k8s-jacoco-operator`

Verify it worked `kubectl run testpod --image=busybox`, this will be changed, fetch it's yaml `kubectl get testpod -o yaml` you will see its `securityContext`'s have been enhanced.
Deploy the operator `helm upgrade --install jacoco-operator k8s/k8s-jacoco-operator`

## Inject the Jacoco Agent
Once you've deployed the operator you can add the following annotations to your pods in the same namespace and they
will have the jacoco agent copied in and the appropriate env vars set so the agent used and the code is instrumented.

## Structure
### [Services](./src/services/)
This is meant to include service abstractions, ideally each service should provide an interface/contract
exposing the functionality that other things in the application need.
### [Entities](./src/entities/)
Currently this is setup to house factories or other items to provide instances of third party things/modules that will be bound by the InversifyJS IoC container so they can be injected into other things with `@inject()`

### [Models](./src/models/)
This houses interfaces/models with little to no logic, the intent is these items can be passed/returned from the abstractions in services and avoid tight coupling to third party types.

### [types.ts](./src/types.ts)
This defines symbols for each type that will be configured in the IoC container, these are used to identify the type when using `@inject(TYPES.Services.Kubernetes)` for example. For more information refer to [inversify](https://github.com/inversify/InversifyJS).


### [inversify.config.ts](./src/inversify.config.ts)
This file maps the types defined in `./src/types.ts` to interface types. For more information refer to [inversify](https://github.com/inversify/InversifyJS).
## NPM Scripts
The following scripts are included in the NPM project configuration
- `lint` lints the source code using eslint
- `lint:fix` automatically fixes any lint errors that can be fixed automatically
- `test` uses jest to run test suites
- `test:e2e` runs e2e test suite, this requires an active helm:deploy
- `build` compiles the typescript into js and places it in the `dist` folder
- `build:image` builds the container image
- `minikube:start` create a minikube k8s cluster
- `minikube:stop` stop minikube but do not delete
- `minikube:delete` delete the minikube cluster
- `helm:addRepos` adds helm repos
- `helm:deployCertManager` deploy cert-manager for TLS
- `helm:deploy` deploy the app to k8s using helm
- `helm:template` print the k8s yaml that would be applied to k8s when using `helm:deploy`
- `helm:uninstall` remove the app from k8s
- `helm:uninstallCertManager` remove cert-manager from the k8s cluster
25 changes: 10 additions & 15 deletions test/spring/petClinic.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ describe('spring/pet-clinic', () => {
containers: [{
name: 'api',
image: 'ghcr.io/curium-rocks/spring-petclinic:latest', // multi-arch spring petclinc image
imagePullPolicy: 'IfNotPresent'
imagePullPolicy: 'Always'
}, {
name: 'debug',
image: 'busybox:latest',
Expand All @@ -88,22 +88,17 @@ describe('spring/pet-clinic', () => {
pod = (await client.listNamespacedPod(NAMESPACE)).body.items.filter((p) => p.metadata?.name === podName)[0]
} while (!pod.status?.conditions?.some((c) => c.status === 'True' && c.type === 'Ready'))
console.log('Pod ready')
// run tests

// shutdown/restart container
let socket: any
const execResult = await new Promise<V1Status>((resolve, reject) => {
return exec.exec(NAMESPACE, podName, 'api', ['/bin/kill', '-s', 'SIGINT', '1'], process.stdout, process.stderr, process.stdin, true, (stat:V1Status) => {
console.log('Finished exec')
resolve(stat)
}).then((s) => {
socket = s
}).catch(reject)

// not ideal, await isn't resolving in ci, fire it and add a sleep for a few seconds
exec.exec(NAMESPACE, podName, 'api', ['/bin/kill', '-s', 'SIGINT', '1'], process.stdout, process.stderr, process.stdin, true, (stat:V1Status) => {
console.log('Finished exec')
}).catch((err) => {
console.error('Error while executing: ' + err)
})
expect(execResult).toBeDefined()
if (socket) {
console.log('Cleaning up socket')
socket.close()
}
await new Promise((resolve) => setTimeout(resolve, 5000))

console.log('Waiting for pod to finish restarting')
do {
pod = (await client.listNamespacedPod(NAMESPACE)).body.items.filter((p) => p.metadata?.name === podName)[0]
Expand Down

0 comments on commit 765045c

Please sign in to comment.