Skip to content

Commit

Permalink
Merge pull request #191 from cheerioskun/master
Browse files Browse the repository at this point in the history
feat: Add support for running helm tests for a release
  • Loading branch information
elenz97 authored Nov 21, 2023
2 parents 15ee7e0 + 811654b commit 872cdd4
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 4 deletions.
41 changes: 41 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"reflect"
"strings"

"golang.org/x/exp/slices"

"k8s.io/apimachinery/pkg/api/errors"

"github.com/spf13/pflag"
Expand Down Expand Up @@ -773,6 +775,28 @@ func (c *HelmClient) GetChart(chartName string, chartPathOptions *action.ChartPa
return helmChart, chartPath, err
}

// RunTests runs the tests that were deployed with the release provided. It returns true
// if all the tests ran successfully and false in all other cases.
// NOTE: error = nil implies that all tests ran to either success or failure.
func (c *HelmClient) RunChartTests(releaseName string) (bool, error) {

client := action.NewReleaseTesting(c.ActionConfig)

if c.Settings.Namespace() == "" {
return false, fmt.Errorf("namespace not set")
}

client.Namespace = c.Settings.Namespace()

rel, err := client.Run(releaseName)
if err != nil && rel == nil {
return false, fmt.Errorf("unable to find release '%s': %v", releaseName, err)
}

// Check that there are no test failures
return checkReleaseForTestFailure(rel) == false, nil
}

// chartExists checks whether a chart is already installed
// in a namespace or not based on the provided chart spec.
// Note that this function only considers the contained chart name and namespace.
Expand Down Expand Up @@ -856,6 +880,23 @@ func updateDependencies(helmChart *chart.Chart, chartPathOptions *action.ChartPa
return helmChart, nil
}

// checkReleaseForTestFailure parses the list of hooks in the release
// and checks the status of the test hooks, returning true if any test has Phase != Succeeded
// Returns false if all tests have passed (including if there are no tests)
func checkReleaseForTestFailure(rel *release.Release) bool {
// Check if any test failed
hooksToCheck := []*release.Hook{}
for _, hook := range rel.Hooks {
// Only check the Phase for events which are supposed to get triggered for "test" hook
if slices.Contains(hook.Events, release.HookTest) {
hooksToCheck = append(hooksToCheck, hook)
}
}
return slices.ContainsFunc(hooksToCheck, func(h *release.Hook) bool {
return h.LastRun.Phase != release.HookPhaseSucceeded
})
}

// mergeRollbackOptions merges values of the provided chart to helm rollback options used by the client.
func mergeRollbackOptions(chartSpec *ChartSpec, rollbackOptions *action.Rollback) {
rollbackOptions.DisableHooks = chartSpec.DisableHooks
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/golang/mock v1.6.0
github.com/pkg/errors v0.9.1
github.com/spf13/pflag v1.0.5
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
helm.sh/helm/v3 v3.11.2
k8s.io/apiextensions-apiserver v0.26.3
k8s.io/apimachinery v0.27.1
Expand Down Expand Up @@ -108,7 +109,7 @@ require (
golang.org/x/net v0.8.0 // indirect
golang.org/x/oauth2 v0.1.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/time v0.1.0 // indirect
Expand Down
8 changes: 5 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
Expand Down Expand Up @@ -836,8 +838,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
Expand Down Expand Up @@ -919,7 +921,7 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
1 change: 1 addition & 0 deletions interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type Client interface {
SetDebugLog(debugLog action.DebugLog)
ListReleaseHistory(name string, max int) ([]*release.Release, error)
GetChart(chartName string, chartPathOptions *action.ChartPathOptions) (*chart.Chart, string, error)
RunChartTests(releaseName string) (bool, error)
}

type RollBack interface {
Expand Down
15 changes: 15 additions & 0 deletions mock/interface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 872cdd4

Please sign in to comment.