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

Test code block from _helpers.tpl #288

Open
vovkanaz opened this issue Jan 25, 2024 · 6 comments
Open

Test code block from _helpers.tpl #288

vovkanaz opened this issue Jan 25, 2024 · 6 comments

Comments

@vovkanaz
Copy link

vovkanaz commented Jan 25, 2024

Hello, is there any way to test such code block inside HELM template
{{- include "setAffinity" . | nindent 8 }}
using https://github.com/helm-unittest/helm-unittest, it seems like it doesn't support/work at least for now.
We haven't found any possibility inside this DOC https://github.com/helm-unittest/helm-unittest/blob/main/DOCUMENT.md

@JuryA
Copy link

JuryA commented Feb 10, 2024

I have shared my workaround for the missing functionality with you earlier (#171 (comment)). We have been using this workaround for our tests for library charts. It involves exploiting the NOTES.txt file, which contains a helper template construct that allows us to test the named template by using a special value. We then compare the output of NOTES.txt with the equalRaw assertion to verify its accuracy. We are currently using this workaround until a better, native solution is available.

@ivankatliarchuk
Copy link
Contributor

If I'm understand you correctly, example

File _affinities.tpl

{{/*
Return a nodeAffinity definition
{{ include "common.affinities.nodes" . -}}
*/}}
{{- define "common.affinities.nodes" -}}
requiredDuringSchedulingIgnoredDuringExecution:
  nodeSelectorTerms:
  - matchExpressions:
    - key: topology.kubernetes.io/zone
      operator: In
      values:
      - antarctica-east1
      - antarctica-west1
  preferredDuringSchedulingIgnoredDuringExecution:
  - weight: 1
    preference:
      matchExpressions:
      - key: another-node-label-key
        operator: In
        values:
        - another-node-label-value
{{- end -}}

File pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity: {{- include "common.affinities.nodes" . | nindent 8 }}

File _test.yaml

---
templates:
  - "pod.yaml"
tests:
  - it: should selects the correct kind and match snapshot
    documentSelector:
      path: kind
      value: Pod
    asserts:
      - matchSnapshot: {}
  - it: should validate path exists
    asserts:
      - exists:
          path: spec.affinity.nodeAffinity

And snapsho

should selects the correct kind and match snapshot:
  1: |
    apiVersion: v1
    kind: Pod
    metadata:
      name: with-node-affinity
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: topology.kubernetes.io/zone
                    operator: In
                    values:
                      - antarctica-east1
                      - antarctica-west1
            preferredDuringSchedulingIgnoredDuringExecution:
              - preference:
                  matchExpressions:
                    - key: another-node-label-key
                      operator: In
                      values:
                        - another-node-label-value
                weight: 1

Everything just works fine. Are you expecting a feature where functions are included directly into test suites? This quite tricky, as there is nothing to generate for helm engine.

@vovkanaz
Copy link
Author

Thanks a lot, @ivankatliarchuk, appreciate it! We've got some help from the CNCF chat and successfully figured it out. The ticket might be closed.

@ivankatliarchuk
Copy link
Contributor

Hi @vovkanaz, would you be able to share a solution here too pls so we can spread the knowledge?

@daniel-b2c2
Copy link

daniel-b2c2 commented Apr 26, 2024

@ivankatliarchuk if I may hijack this ticket.

So if you have a _affinities.tpl which defines a template common.affinities.nodes it would be nice to be able to reason about this template directly without going indirectly through actual chart resources, to make it clear what this template is doing. In your case it's obvious but sometimes these templates can be complex or provide specific functionality which we would like to reason about.

Suppose the definition was:

default .Release.Name .Values.nameOverride | trunc 63 | trimSuffix "-"

One might call the above template with different contexts e.g. Release.Name, or Values.nameOverride set, with values over 63 characters, and values ending in - to capture the behaviour of this template.

for
  _affinities.tpl
when 
  .Release.Name = bob
  .Values.nameOverride = abcde-
expectResult:
  abcde  // see hyphen suffix removed

This nails down the functionality in that template without needing external resources like Pods or ConfigMaps.
The advantage here is that if the resource we pick to test the functionality, say Pod, is subject to change and stops referencing the functionality in affinities.tpl, the definition still exists, it still needs testing, but now there is no test coverage just because one resource that we happened to use for testing purposes no longer uses the template.

Being able to test the template directly has its advantages. I see the suggestion you made earlier as more of an integration test for the chart overall, what I'm looking for here, would be more like a unit test for the tpl file.

I hope my question makes sense?

@ivankatliarchuk
Copy link
Contributor

I would agree on that. Currently charts I'm looking after have quite a decent amount of *.tpl functions too. The helm behavior is a challenging part here. The tpl function is not rendered on its own, it require an import/include within a template.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants