feat: Allow helm test to run a subset of tests

Signed-off-by: Chris Wells <chriswells0@users.noreply.github.com>
pull/8484/head
Chris Wells 5 years ago
parent 84b02bbee3
commit 2a7a98ae5a

@ -19,6 +19,8 @@ package main
import (
"fmt"
"io"
"regexp"
"strings"
"time"
"github.com/spf13/cobra"
@ -39,6 +41,7 @@ func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command
client := action.NewReleaseTesting(cfg)
var outfmt = output.Table
var outputLogs bool
var filter []string
cmd := &cobra.Command{
Use: "test [RELEASE]",
@ -53,6 +56,14 @@ func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command
},
RunE: func(cmd *cobra.Command, args []string) error {
client.Namespace = settings.Namespace()
notName := regexp.MustCompile(`^!\s?name=`)
for _, f := range filter {
if strings.HasPrefix(f, "name=") {
client.Filters["name"] = append(client.Filters["name"], strings.TrimPrefix(f, "name="))
} else if notName.MatchString(f) {
client.Filters["!name"] = append(client.Filters["!name"], notName.ReplaceAllLiteralString(f, ""))
}
}
rel, runErr := client.Run(args[0])
// We only return an error if we weren't even able to get the
// release, otherwise we keep going so we can print status and logs
@ -80,6 +91,7 @@ func newReleaseTestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command
f := cmd.Flags()
f.DurationVar(&client.Timeout, "timeout", 300*time.Second, "time to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&outputLogs, "logs", false, "dump the logs from test pods (this runs after all tests are complete, but before any cleanup)")
f.StringSliceVar(&filter, "filter", []string{}, "specify tests by attribute (currently \"name\") using attribute=value syntax or '!attribute=value' to exclude a test (can specify multiple or separate values with commas: name=test1,name=test2)")
return cmd
}

@ -1,3 +1,3 @@
apiVersion: v1
entries: {}
generated: "2020-06-23T10:01:59.2530763-07:00"
generated: "2020-09-09T19:50:50.198347916-04:00"

@ -37,12 +37,14 @@ type ReleaseTesting struct {
Timeout time.Duration
// Used for fetching logs from test pods
Namespace string
Filters map[string][]string
}
// NewReleaseTesting creates a new ReleaseTesting object with the given configuration.
func NewReleaseTesting(cfg *Configuration) *ReleaseTesting {
return &ReleaseTesting{
cfg: cfg,
Filters: map[string][]string{},
}
}
@ -62,11 +64,37 @@ func (r *ReleaseTesting) Run(name string) (*release.Release, error) {
return rel, err
}
skippedHooks := []*release.Hook{}
executingHooks := []*release.Hook{}
if len(r.Filters["!name"]) != 0 {
for _, h := range rel.Hooks {
if contains(r.Filters["!name"], h.Name) {
skippedHooks = append(skippedHooks, h)
} else {
executingHooks = append(executingHooks, h)
}
}
rel.Hooks = executingHooks
}
if len(r.Filters["name"]) != 0 {
executingHooks = nil
for _, h := range rel.Hooks {
if contains(r.Filters["name"], h.Name) {
executingHooks = append(executingHooks, h)
} else {
skippedHooks = append(skippedHooks, h)
}
}
rel.Hooks = executingHooks
}
if err := r.cfg.execHook(rel, release.HookTest, r.Timeout); err != nil {
rel.Hooks = append(skippedHooks, rel.Hooks...)
r.cfg.Releases.Update(rel)
return rel, err
}
rel.Hooks = append(skippedHooks, rel.Hooks...)
return rel, r.cfg.Releases.Update(rel)
}
@ -99,3 +127,12 @@ func (r *ReleaseTesting) GetPodLogs(out io.Writer, rel *release.Release) error {
}
return nil
}
func contains(arr []string, value string) bool {
for _, item := range arr {
if item == value {
return true
}
}
return false
}

Loading…
Cancel
Save