All Plugins contributed to Plugin-Extensions repository should include comprehensive Helm Chart Tests using the bats/bats-detik
testing framework. This ensures our Plugins are robust, deployable, and catch potential issues early in the development cycle.
What is bats/bats-detik?
The bats/bats-detik framework simplifies end-to-end (e2e) Testing in Kubernetes. It combines the Bash Automated Testing System (bats
) with Kubernetes-specific assertions (detik
). This allows you to write test cases using natural language-like syntax, making your tests easier to read and maintain.
Implementing Tests
Create a /tests
folder inside your Plugin’s Helm Chart templates
folder to store your test resources.
ConfigMap definition:
test-<plugin-name>-config.yaml
file in the templates/tests
directory to define a ConfigMap
that will hold your test script.ConfigMap
contains the test script run.sh
that will be executed by the test Pod
to run your tests.{{- if .Values.testFramework.enabled -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-test
namespace: {{ .Release.Namespace }}
labels:
type: integration-test
data:
run.sh: |-
#!/usr/bin/env bats
load "/usr/lib/bats/bats-detik/utils"
load "/usr/lib/bats/bats-detik/detik"
DETIK_CLIENT_NAME="kubectl"
@test "Verify successful deployment and running status of the {{ .Release.Name }}-operator pod" {
verify "there is 1 deployment named '{{ .Release.Name }}-operator'"
verify "there is 1 service named '{{ .Release.Name }}-operator'"
try "at most 2 times every 5s to get pods named '{{ .Release.Name }}-operator' and verify that '.status.phase' is 'running'"
}
@test "Verify successful creation and bound status of {{ .Release.Name }} persistent volume claims" {
try "at most 3 times every 5s to get persistentvolumeclaims named '{{ .Release.Name }}.*' and verify that '.status.phase' is 'Bound'"
}
@test "Verify successful creation and available replicas of {{ .Release.Name }} Prometheus resource" {
try "at most 3 times every 5s to get prometheuses named '{{ .Release.Name }}' and verify that '.status.availableReplicas' is more than '0'"
}
@test "Verify creation of required custom resource definitions (CRDs) for {{ .Release.Name }}" {
verify "there is 1 customresourcedefinition named 'prometheuses'"
verify "there is 1 customresourcedefinition named 'podmonitors'"
}
{{- end -}}
Note: You can use this guide for reference when writing your test assertions.
Test Pod Definition:
test-<plugin-name>.yaml
file in the templates/tests
directory to define a Pod
that will run your tests.Pod
will mount the ConfigMap
created in the previous step and will execute the test script run.sh
.{{- if .Values.testFramework.enabled -}}
apiVersion: v1
kind: Pod
metadata:
name: {{ .Release.Name }}-test
namespace: {{ .Release.Namespace }}
labels:
type: integration-test
annotations:
"helm.sh/hook": test
"helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded"
spec:
serviceAccountName: {{ .Release.Name }}-test
containers:
- name: bats-test
image: "{{ .Values.testFramework.image.registry}}/{{ .Values.testFramework.image.repository}}:{{ .Values.testFramework.image.tag }}"
imagePullPolicy: {{ .Values.testFramework.image.pullPolicy }}
command: ["bats", "-t", "/tests/run.sh"]
volumeMounts:
- name: tests
mountPath: /tests
readOnly: true volumes:
- name: tests
configMap:
name: {{ .Release.Name }}-test
restartPolicy: Never
{{- end -}}
templates/tests
folder with a dedicated ServiceAccount
and role authorisations so that the test Pod
can cover test the cases.kube-monitoring
as a reference to configure RBAC permissions for your test Pod.values.yaml
:values.yaml
file:testFramework:
enabled: true
image:
registry: ghcr.io
repository: cloudoperators/greenhouse-extensions-integration-test
tag: main
imagePullPolicy: IfNotPresent
Important: Once you have completed all the steps above, you are ready to run the tests. However, before running the tests, ensure that you perform a fresh Helm installation or upgrade of your Plugin’s Helm release against your test Kubernetes cluster (for example, Minikube or Kind) by executing the following command:
# For a new installation
helm install <Release name> <chart-path>
# For an upgrade
helm upgrade <Release name> <chart-path>
helm test <Release name>
Some Plugins require other Plugins to be installed in the Cluster for their tests to run successfully. To support this, each Plugin can declare required dependencies using a test-dependencies.yaml
file.
[!NOTE]
Thetest-dependencies.yaml
file is required if other Plugins need to be installed in the Kind Cluster created by the GitHub Actions workflow before running tests during a Pull Request for the Plugin.
test-dependencies.yaml
file in the Plugin’s root directory (e.g., Thanos/test-dependencies.yaml
).test-dependencies.yaml
dependencies:
- kube-monitoring
values:
kubeMonitoring:
prometheus:
enabled: true
serviceMonitor:
enabled: false
prometheusSpec:
thanos:
objectStorageConfig:
secret:
type: FILESYSTEM
config:
directory: "/test"
prefix: ""
In this example, the Plugin:
kube-monitoring
as a dependency that must be installed firstThe test-dependencies.yaml
file supports:
The GitHub Actions workflow automatically:
test-dependencies.yaml
for each changed Plugin if present.<plugin-name>/ci/test-values.yaml
filevalues.yaml
test-dependencies.yaml
file.test-dependencies.yaml
file will override the default values of the dependent Plugins.alert/
├── charts/
├── ci/
│ └── test-values.yaml
└── test-dependencies.yaml
Contribution Checklist
Before submitting a Pull Request:
/tests
directory.test-<plugin-name>.yaml
, test-<plugin-name>-config.yaml
, and test-permissions.yaml
files.helm test <release-name>
and confirm that all tests pass against a test Kubernetes Cluster.Important Notes