Skip to content

Commit

Permalink
feat(chart): add helm-unittest framework (#5137)
Browse files Browse the repository at this point in the history
* feat(chart): add helm-unittest framework

Signed-off-by: ivan katliarchuk <[email protected]>

* feat(chart): add helm-unittest framework

Signed-off-by: ivan katliarchuk <[email protected]>

* feat(chart): add helm-unittest framework

Signed-off-by: ivan katliarchuk <[email protected]>

* feat(chart): add helm-unittest framework

Signed-off-by: ivan katliarchuk <[email protected]>

* feat(chart): add helm-unittest framework

Signed-off-by: ivan katliarchuk <[email protected]>

* feat(chart): add helm-unittest framework

* feat(chart): add helm-unittest framework

Signed-off-by: ivan katliarchuk <[email protected]>

* feat(chart): add helm-unittest framework

Signed-off-by: ivan katliarchuk <[email protected]>

* feat(chart): add helm-unittest framework

Signed-off-by: ivan katliarchuk <[email protected]>

* feat(chart): add helm-unittest framework

Signed-off-by: ivan katliarchuk <[email protected]>

* feat(chart): add helm-unittest framework

Signed-off-by: ivan katliarchuk <[email protected]>

* feat(chart): add helm-unittest framework

Signed-off-by: ivan katliarchuk <[email protected]>

* feat(chart): add helm-unittest framework

Signed-off-by: ivan katliarchuk <[email protected]>

---------

Signed-off-by: ivan katliarchuk <[email protected]>
  • Loading branch information
ivankatliarchuk authored Mar 4, 2025
1 parent 7c23e01 commit 5f26223
Show file tree
Hide file tree
Showing 16 changed files with 683 additions and 5 deletions.
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/.helmignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@
ci/
schema/
.schema.yaml
tests/
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

0 comments on commit 5f26223

Please sign in to comment.