Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(chart): add helm-unittest framework #5137

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/lint-test-chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ jobs:
exit 1
fi

- name: Run Helm Unit Tests
run: |
set -euo pipefail
helm plugin install https://github.com/helm-unittest/helm-unittest.git >/dev/null 2>&1
helm unittest -f 'tests/*_test.yaml' --color charts/external-dns

- name: Install Artifact Hub CLI
uses: action-stars/install-tool-from-github-release@ece2623611b240002e0dd73a0d685505733122f6 # v0.2.4
with:
Expand Down
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,11 @@ pre-commit-validate:
#? help: Get more info on available commands
help: Makefile
@sed -n 's/^#?//p' $< | column -t -s ':' | sort | sed -e 's/^/ /'

#? helm-test: Run unit tests
helm-test:
scripts/helm-tools.sh --helm-unittest

#? helm-template: Run helm template
helm-template:
scripts/helm-tools.sh --helm-template
1 change: 1 addition & 0 deletions charts/external-dns/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added helm testing framework `helm plugin unittest`. ([#5137](https://github.com/kubernetes-sigs/external-dns/pull/5137)) _@ivankatliarchuk_
- Added ability to generate schema with `helm plugin schema`. ([#5075](https://github.com/kubernetes-sigs/external-dns/pull/5075)) _@ivankatliarchuk_
- Added `docs/contributing/dev-guide.md#helm-values` guide. ([#5075](https://github.com/kubernetes-sigs/external-dns/pull/5075)) _@ivankatliarchuk_

Expand Down
29 changes: 29 additions & 0 deletions charts/external-dns/tests/common-metadata_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
suite: All resources contains metadata
templates:
- "*.yaml"
release:
name: external-dns
chart:
version: "1.15.0"
appVersion: "0.15.0"
tests:
- it: "should contain labels metadata in each template"
set:
secretConfiguration:
enabled: true
mountPath: "/etc/kubernetes/"
serviceMonitor:
enabled: true
asserts:
- exists:
path: metadata.labels
- isNotEmpty:
path: metadata.labels
- equal:
path: metadata.labels
value:
helm.sh/chart: external-dns-1.15.0
app.kubernetes.io/name: external-dns
app.kubernetes.io/instance: external-dns
app.kubernetes.io/version: "0.15.0"
app.kubernetes.io/managed-by: Helm
80 changes: 80 additions & 0 deletions charts/external-dns/tests/deployment-config_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
suite: Deployment configuration
templates:
- deployment.yaml
release:
namespace: default
tests:
- it: should provide expected defaults
asserts:
- isKind:
of: Deployment
- hasDocuments:
count: 1
- equal:
path: spec.replicas
value: 1
- equal:
path: spec.strategy.type
value: Recreate
- equal:
path: metadata.namespace
value: default
- notExists:
path: spec.template.spec.automountServiceAccountToken

- it: should provide expected defaults for securityContext
asserts:
- isSubset:
path: spec.template.spec.containers[?(@.name == "external-dns")]
content:
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 65532
runAsNonRoot: true
runAsUser: 65532

- it: should provide expected defaults for liveness and readiness
asserts:
- isSubset:
path: spec.template.spec.containers[?(@.name == "external-dns")]
content:
readinessProbe:
failureThreshold: 6
httpGet:
path: /healthz
port: http
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
livenessProbe:
failureThreshold: 2
httpGet:
path: /healthz
port: http
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5

- it: should have service account set
release:
name: test
asserts:
- equal:
path: spec.template.spec.serviceAccountName
value: test-external-dns

- it: should have not be able to change replicas when specified via values
set:
deployment:
replicas: 3
asserts:
- equal:
path: spec.replicas
value: 1
119 changes: 119 additions & 0 deletions charts/external-dns/tests/deployment-flags_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
suite: Deployment flags configurations
templates:
- deployment.yaml
release:
namespace: default
tests:
- it: should provide expected default flags
asserts:
# - matchSnapshot: {}
- exists :
path: spec.template.spec.containers[?(@.name == "external-dns")]
- equal :
path: spec.template.spec.containers[?(@.name == "external-dns")].args
value:
- --log-level=info
- --log-format=text
- --interval=1m
- --source=service
- --source=ingress
- --policy=upsert-only
- --registry=txt
- --provider=aws

- it: should configure txtPrefix and ignore txtSuffix if not empty
set:
provider:
name: cloudflare
txtPrefix: "test-prefix"
txtSuffix: "test-suffix"
txtOwnerId: "testing"
asserts:
- exists :
path: spec.template.spec.containers[?(@.name == "external-dns")]
- equal :
path: spec.template.spec.containers[?(@.name == "external-dns")].args
value:
- --log-level=info
- --log-format=text
- --interval=1m
- --source=service
- --source=ingress
- --policy=upsert-only
- --registry=txt
- --txt-owner-id=testing
- --txt-prefix=test-prefix
- --provider=cloudflare
- notContains:
path: spec.template.spec.containers[?(@.name == "external-dns")].args
content: "--txt-suffix=test-suffix"

- it: should configure 'txtSuffix' when not empty with 'txtPrefix' empty
set:
txtPrefix: ""
txtSuffix: "test-suffix"
asserts:
- exists :
path: spec.template.spec.containers[?(@.name == "external-dns")]
- equal :
path: spec.template.spec.containers[?(@.name == "external-dns")].args
value:
- --log-level=info
- --log-format=text
- --interval=1m
- --source=service
- --source=ingress
- --policy=upsert-only
- --registry=txt
- --txt-suffix=test-suffix
- --provider=aws
- notContains:
path: spec.template.spec.containers[?(@.name == "external-dns")].args
content: "--txt-prefix=test-prefix"

- it: should be able configure multiple sources
set:
sources:
- fake
- crd
asserts:
- contains:
path: spec.template.spec.containers[?(@.name == "external-dns")].args
content: "--source=fake"
- contains:
path: spec.template.spec.containers[?(@.name == "external-dns")].args
content: "--source=crd"

- it: should be able to configure in single namespace
set:
namespaced: true
asserts:
- contains:
path: spec.template.spec.containers[?(@.name == "external-dns")].args
content: "--namespace=default"

- it: should manage multiple zones with 'extraArgs'
set:
extraArgs:
- --zone-id-filter=/hostedzone/Z00001
- --zone-id-filter=/hostedzone/Z00002
- --zone-id-filter=/hostedzone/Z00003
- --zone-id-filter=/hostedzone/Z00004
- --zone-id-filter=/hostedzone/Z00005
asserts:
- equal:
path: spec.template.spec.containers[?(@.name == "external-dns")].args
value:
- --log-level=info
- --log-format=text
- --interval=1m
- --source=service
- --source=ingress
- --policy=upsert-only
- --registry=txt
- --provider=aws
- --zone-id-filter=/hostedzone/Z00001
- --zone-id-filter=/hostedzone/Z00002
- --zone-id-filter=/hostedzone/Z00003
- --zone-id-filter=/hostedzone/Z00004
- --zone-id-filter=/hostedzone/Z00005
118 changes: 118 additions & 0 deletions charts/external-dns/tests/deployment-scheduling_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
suite: Deployment scheduling configuration
templates:
- deployment.yaml
release:
namespace: default
tests:
- it: should not provide defaults for affinities or tolerations
asserts:
- isKind:
of: Deployment
- notExists:
path: spec.template.spec.tolerations
- notExists:
path: spec.template.spec.affinity

- it: should provide support for custom affinities
set:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- zoneA
- zoneB
asserts:
- equal:
path: spec.template.spec.affinity
value:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- zoneA
- zoneB

- it: should provide support for configuring node and pod affinities
set:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: kubernetes.io/hostname
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- test-pod-scheduling-config
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: datadog-agent
operator: In
values:
- standard
- key: iam/scope
operator: In
values:
- namespace
asserts:
- equal:
path: spec.template.spec.affinity
value:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: datadog-agent
operator: In
values:
- standard
- key: iam/scope
operator: In
values:
- namespace
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- test-pod-scheduling-config
topologyKey: kubernetes.io/hostname

- it: should provide support for configuring tolerations
set:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
- key: iam/scope
operator: Equal
value: namespace
effect: NoExecute
asserts:
- notExists:
path: spec.template.spec.affinity
- exists:
path: spec.template.spec.tolerations
- equal:
path: spec.template.spec.tolerations
value:
- effect: NoSchedule
key: key1
operator: Equal
value: value1
- effect: NoExecute
key: iam/scope
operator: Equal
value: namespace
Loading
Loading