quintush / helm-unittest

BDD styled unit test framework for Kubernetes Helm charts as a Helm plugin.
MIT License
344 stars 69 forks source link

using matchRegex, notMatchRegex or similar with rendered heredocs - configmaps #66

Closed isindir closed 4 years ago

isindir commented 4 years ago

Hello,

looks like it is not possible to do with current state of the plugin following:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ template "my-chart.fullname" . }}
data:
  my.conf: |
    {{- if .Values.expose }}
    cacertfile            = /etc/cert/cacert.pem
    certfile              = /etc/cert/tls.crt
    keyfile               = /etc/cert/tls.key
    verify                = verify_none
    {{- end }}
    abc                   = qqq
    qqq                   = abc

and I'm trying to create a test for it, where default expose: false:

- it: should NOT configure ssl params if NOT set to be exposed
  asserts:
    - notMatchRegex:
        path: data.my\.conf
        value: cacertfile

which fails with something similar to:

 FAIL  abc tests        tests/abc_test.yaml
        - should NOT configure ssl params if NOT set to be exposed

                - asserts[0] `notMatchRegex` fail

                        Template:       my-chart/templates/abc-cm.yaml
                        DocumentIndex:  0
                        Path:   data.my\.conf
                        Expected NOT to match:
                        Actual: abc                   = qqq
                                qqq                   = abc

matchRegex and notMatchRegex are using regex only for a string, but in the case I have that is multiline string and also not a yaml, where potentially that would work if full path would be used. Looks like pretty standard use case . Is it possible to introduce a new set of regex operations which would squash multiline heredoc into single line blob, which then is possible to test using it ?

Thanks

quintush commented 4 years ago

Hello @isindir,

Thanks for the feedback. Based on your example it seems that the regex is indeed not validating against multi-line values.

I will look info thisand hope to have a fix soon.

Greetings, @quintush

xordspar0 commented 4 years ago

The problem isn't that there's a bug related to multiline strings, the problem is in your test assertion.

- notMatchRegex:
    path: data.my\.conf
    value: cacertfile

The matchRegex and notMatchRegex assertions use the pattern field to specify the pattern you want to match, not value. It should be

- notMatchRegex:
    path: data.my\.conf
    pattern: cacertfile

it seems that the regex is indeed not validating against multi-line values

I can't reproduce this, but note that some of the unit tests in match_regex_validator_test.go test with a pattern like "^hello". In Go regexp syntax, the ^ operator matches the beginning of the string, not the beginning of each line (unless you use the m flag). Maybe that's why you saw something unexpected with multiline stings.

isindir commented 4 years ago

@xordspar0 , thanks. I'll play with that again, looks like a mistake of mine. Anyway, the idea of the test was to test if configmap file gets specific content if helm value is set or not. Naturaly I was thinking to do a simple regex match and if any line is matched - return true.

isindir commented 4 years ago

@xordspar0 @quintush - I was able to make my tests working. This is not an issue, just my mistake based on copy paste - value instead of pattern. Thanks

quintush commented 4 years ago

Hello @xordspar0, @isindir,

Thanks for the feedback!

@xordspar0, i have added the scenario as testcase.

@isindir, based on the feedback i have added additional validation that the pattern field should be filled.

Greetings, @quintush

xordspar0 commented 4 years ago

@isindir, based on the feedback i have added additional validation that the pattern field should be filled.

Great idea, that will help in the future.