vbehar / helm3-unittest

Fork of lrills/helm-unittest but for Helm 3
MIT License
21 stars 10 forks source link

feature: edit release information on test, and reference maps #8

Closed TheQueenIsDead closed 1 year ago

TheQueenIsDead commented 2 years ago

Hi,

Currently I see it's possible to set values, but not alter other Helm metadata before running a test. Would it be possible to adjust the templating to include the ability to adjust values such as .Release.Namespace?

While here, is it possible to make assertions based on the value of a map where the key contains .'s? For example it would be awesome to be able to reference something like this for an Ingress

suite: test ingress
templates:
  - ingress.yaml
tests:
  - it: should include a default nginx snippet when not set by user
    asserts:
      - equal:
          path: metadata.annotations['nginx.ingress.kubernetes.io/configuration-snippet']
          value: "example stuff and things"

Apologies if it's already possible to do this, any help appreciated :-)

cyberhck commented 2 years ago

did you figure out a way for this?

TheQueenIsDead commented 2 years ago

Hi @cyberhck , no I did not find a way around this.

I instead opted to move away from the helm unittest plugin, and chose to perform unit tests using Terratest which provides much more flexibility for testing. It does this by allowing configurable kubectl and helm settings, as well as being able to use native Golang test suites to create assertions, and can unmarshal rendered yaml into kubernetes api structs for verification.

A nice example of this can be found on their blog: https://blog.gruntwork.io/automated-testing-for-kubernetes-and-helm-charts-using-terratest-a4ddc4e67344#d009

An example of setting the namespace, and referencing annotations with dots in the name, might look like the following:

func TestIngressAnnotationst *testing.T) {

    // Assemble
    releaseName := "release-name"
    namespaceName := "release-namespace"
    options := &helm.Options{
        KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
        ValuesFiles: []string{
            "./test.values.yaml",
        },
    }

    // Act
    output := helm.RenderTemplate(t, options, ChartLocation, releaseName, []string{IngressManifestLocation})
    // Use kubernetes/client-go library to render the template output into the Ingress struct.
    var ingress networkingv1.Ingress
    helm.UnmarshalK8SYaml(t, output, &ingress)

    // Assert
    ingressAnnotations := ingress.ObjectMeta.Annotations

    // Assert that our custom fixture annotation has been added, and verify expected value.
    assert.Contains(t, ingressAnnotations, "example.my.business.anno/example")
    assert.Equal(t, "expectedvalue", ingressAnnotations["example.my.business.anno/example"])
}

I know it does not remedy the issue present for this plugin, but if it's possible for you to pivot to Terratest I would recommend it. After a short learning curve I have had some really superb success.

TheQueenIsDead commented 2 years ago

@cyberhck it looks like this repo isnt maintained, there is a fork of the original helm unittest below which seems more actively maintained: https://github.com/quintush/helm-unittest

cyberhck commented 2 years ago

Thanks @TheQueenIsDead , that's what I've switched to as well :)