Skip to content

Commit

Permalink
e2e: Replace Kuttl-in-Kuttl (#131)
Browse files Browse the repository at this point in the history
  • Loading branch information
bcm820 authored Feb 22, 2024
1 parent 951b4db commit 2f93bfc
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 163 deletions.
22 changes: 0 additions & 22 deletions e2e/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,6 @@ _runThisTest:
cp -r $(PWD) $$D/suit ;\
ROOT_DIR=$(ROOT_DIR) KUBECONFIG="$(ROOT_DIR)/kubeconfig" kubectl-kuttl test --timeout 300 --skip-delete "$$D/suit"

runTestSuit:
@T="$$(KUBECONFIG="$$ROOT_DIR/kubeconfig" kubectl-kuttl test --timeout 300 --skip-delete --namespace "$$NAMESPACE" "$$TS" 2>&1)" ;\
echo "$$T" |\
grep -v harness.go |\
grep -v ^=== |\
grep -v "running without a 'kuttl-test.yaml" |\
grep -v "creation of user-supplied namespace" |\
grep -v "not match file name regexp" |\
grep -v "kutt-test config testdirs is overridden" ;\
echo "$$T" | \
grep '^PASS' || \
(echo "$$T" | grep harness.go && find $$TS -name *.yaml -exec cat {} \; && exit 1)

renderTestCase:
@D="$$(mktemp -d)" ;\
mkdir -p "$$D/case" ;\
envsubst -i "$$TPL" -o "$$D/case/00-case.yaml" ;\
printf "$$D\n"

renderManifest:
@echo $(shell make --no-print-directory renderTestCase)/case/00-case.yaml

getKubeUid:
@kubectl get -o jsonpath='{.metadata.uid}' -n "$$NAMESPACE" "$$OBJ"

Expand Down
72 changes: 21 additions & 51 deletions e2e/README.MD
Original file line number Diff line number Diff line change
@@ -1,68 +1,38 @@
# E2E Framework

The E2E framework uses Kuttl under the hood. Kuttl is a simple and most importantly static tool.
That means there is no way to dynamically generate manifests.
The solution is KIK (Kuttl-In-Kuttl)!
The E2E framework uses Kuttl under the hood. Kuttl is a simple and most importantly static tool that handles applying manifests for running assertions in a namespace it generates for each test.

## Kuttl-In-Kuttl
In order to dynamically generate manifests, Kuttl supports declaring a `TestStep` manifest which includes an option for running scripts. This allows us apply manifests with dynamic values from stdin.

## How does it work
Additionally, helper functions can be invoked in the scripts by creating a Makefile in each test folder that references `../../Makefile` (i.e. `e2e/Makefile`).

- Instead of creating a static Kuttl manifest, you can create template. Template extension must be `.yml` otherwise Kuttl starts executing it.
- Template is rendered via `envsubst`, so you can use Bash variables for dynamic data injection.
- Variables always present
- `${KUBECONFIG}`
- `${NAMESPACE}`
- `${ROOT_DIR}`
## Example TestStep

Example template
```yaml
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: LinodeMachine
metadata:
ownerReferences:
- apiVersion: cluster.x-k8s.io/v1beta1
kind: Machine
name: machine-sample
uid: ${MACHINE_UID}
name: linodemachine-sample
spec:
region: us-sea
type: g5-nanode-1
```
- Helper tools are available, please create a Makefile in your test folder. In this way you can use built in helpers without including any script in the test, plus this file is a good place for test specific helpers.
Example Makefile
```makefile
include ../../Makefile
```

- Template is nothing without a runner, please use helpers provided in Makefile to render and run template.

Example template runner
```yaml
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- script: |-
MACHINE_UID="$(OBJ=machines/machine-sample make getKubeUid)" \
TS="$(TPL="$PWD/02-create-linodemachine.tpl.yml" make renderTestCase)" make runTestSuit
cat <<EOF | kubectl apply -n $NAMESPACE -f -
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: LinodeMachine
metadata:
ownerReferences:
- apiVersion: cluster.x-k8s.io/v1beta1
kind: Machine
name: machine-sample
uid: $(OBJ=machines/machine-sample make getKubeUid)
name: linodemachine-sample
spec:
region: us-sea
type: g5-nanode-1
EOF
```
- You can run testsuits (which can contain template rendering).
Example testsuit runner:
```yaml
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- script: TS="$PWD/testsuit" make runTestSuit
```
## Test Execution
- Test execution order is not guaranteed. If a test depends on another resource it is strongly suggested to create `assert` files to wait for an event. Almost every test depends on CAPI providers, so there is a good chance, you have to create a `00-assert.yaml` in your test folder.
Note that test execution order is not guaranteed. If a test depends on another resource it is strongly suggested to create `assert` files to wait for an event. Almost every test depends on CAPI providers, so there is a good chance you have to create a `00-assert.yaml` in your test folder that asserts the following:

Example `00-assert.yaml`:
```yaml
apiVersion: apps/v1
kind: Deployment
Expand All @@ -81,7 +51,7 @@ status:
availableReplicas: 1
```

## Executing individual test suit
## Executing individual tests

```bash
make _e2etest-infra # Only once per cluster!
Expand Down
48 changes: 0 additions & 48 deletions e2e/linodemachine-controller/byovpc/01-create-cluster.tpl.yml

This file was deleted.

66 changes: 62 additions & 4 deletions e2e/linodemachine-controller/byovpc/01-create-cluster.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,67 @@ kind: TestStep
commands:
- command: make createVPC
- script: |-
VPC_ID=$(make fetchVPCID) \
TS="$(TPL="$PWD/01-create-vpc.tpl.yml" make renderTestCase)" make runTestSuit
cat <<EOF | kubectl apply -n $NAMESPACE -f -
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: LinodeVPC
metadata:
annotations:
cluster.x-k8s.io/paused: "true"
name: linodevpc-sample
spec:
label: capli-e2e-byovpc-for-all-tests
region: us-sea
vpcID: $(make fetchVPCID)
EOF
- command: make enableVPC
- script: |-
VPC_UID="$(OBJ=linodevpcs/linodevpc-sample make getKubeUid)" \
TS="$(TPL="$PWD/01-create-cluster.tpl.yml" make renderTestCase)" make runTestSuit
cat <<EOF | kubectl apply -n $NAMESPACE -f -
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: LinodeCluster
metadata:
annotations:
cluster.x-k8s.io/paused: "true"
name: linodecluster-sample
spec:
region: us-sea
vpcRef:
kind: LinodeVPC
name: linodevpc-sample
namespace: $NAMESPACE
uid: $(OBJ=linodevpcs/linodevpc-sample make getKubeUid)
---
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
annotations:
cluster.x-k8s.io/paused: "true"
name: cluster-sample
spec:
paused: true
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: LinodeCluster
name: linodecluster-sample
---
apiVersion: cluster.x-k8s.io/v1beta1
kind: Machine
metadata:
annotations:
cluster.x-k8s.io/paused: "true"
name: machine-sample
spec:
clusterName: cluster-sample
bootstrap:
configRef:
apiVersion: v1
kind: "ConfigMap"
name: "boostrap-sample"
dataSecretName: bootstrap-data-sample
---
apiVersion: v1
kind: Secret
metadata:
name: bootstrap-data-sample
data:
value: dG91Y2ggL29rCg==
EOF
10 changes: 0 additions & 10 deletions e2e/linodemachine-controller/byovpc/01-create-vpc.tpl.yml

This file was deleted.

This file was deleted.

16 changes: 14 additions & 2 deletions e2e/linodemachine-controller/byovpc/02-create-linodemachine.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,17 @@ apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- script: |-
MACHINE_UID="$(OBJ=machines/machine-sample make getKubeUid)" \
TS="$(TPL="$PWD/02-create-linodemachine.tpl.yml" make renderTestCase)" make runTestSuit
cat <<EOF | kubectl apply -n $NAMESPACE -f -
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: LinodeMachine
metadata:
ownerReferences:
- apiVersion: cluster.x-k8s.io/v1beta1
kind: Machine
name: machine-sample
uid: $(OBJ=machines/machine-sample make getKubeUid)
name: linodemachine-sample
spec:
region: us-sea
type: g5-nanode-1
EOF

This file was deleted.

16 changes: 14 additions & 2 deletions e2e/linodemachine-controller/minimal/02-create-linodemachine.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,17 @@ apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- script: |-
MACHINE_UID="$(OBJ=machines/machine-sample make getKubeUid)" \
TS="$(TPL="$PWD/02-create-linodemachine.tpl.yml" make renderTestCase)" make runTestSuit
cat <<EOF | kubectl apply -n $NAMESPACE -f -
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1
kind: LinodeMachine
metadata:
ownerReferences:
- apiVersion: cluster.x-k8s.io/v1beta1
kind: Machine
name: machine-sample
uid: $(OBJ=machines/machine-sample make getKubeUid)
name: linodemachine-sample
spec:
region: us-sea
type: g5-nanode-1
EOF

0 comments on commit 2f93bfc

Please sign in to comment.