2017-01-04 10:13:26 -05:00
/ *
2018-08-24 15:03:55 -04:00
Copyright The Helm Authors .
2017-01-04 10:13:26 -05:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2025-02-24 10:11:54 -05:00
package cmd
2017-01-04 10:13:26 -05:00
import (
2025-06-10 18:15:26 -04:00
"errors"
2019-10-17 17:27:19 -04:00
"fmt"
2017-01-04 10:13:26 -05:00
"io"
2020-07-19 14:26:48 -04:00
"regexp"
"strings"
2019-09-05 13:23:20 -04:00
"time"
2017-01-04 10:13:26 -05:00
"github.com/spf13/cobra"
2024-12-26 16:33:51 -05:00
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/cli/output"
2025-02-24 10:11:54 -05:00
"helm.sh/helm/v4/pkg/cmd/require"
2017-01-04 10:13:26 -05:00
)
2019-04-23 12:07:42 -04:00
const releaseTestHelp = `
2019-09-05 13:23:20 -04:00
The test command runs the tests for a release .
2017-01-04 10:13:26 -05:00
2019-09-05 13:23:20 -04:00
The argument this command takes is the name of a deployed release .
The tests to be run are defined in the chart that was installed .
2017-01-04 10:13:26 -05:00
`
2019-02-08 19:02:57 -05:00
func newReleaseTestCmd ( cfg * action . Configuration , out io . Writer ) * cobra . Command {
2019-09-05 13:23:20 -04:00
client := action . NewReleaseTesting ( cfg )
2024-11-15 13:27:28 -05:00
outfmt := output . Table
2019-10-17 17:27:19 -04:00
var outputLogs bool
2020-07-19 14:26:48 -04:00
var filter [ ] string
2019-09-05 13:23:20 -04:00
2017-01-04 10:13:26 -05:00
cmd := & cobra . Command {
2019-09-05 13:23:20 -04:00
Use : "test [RELEASE]" ,
Short : "run tests for a release" ,
2019-04-23 12:07:42 -04:00
Long : releaseTestHelp ,
2019-09-05 13:23:20 -04:00
Args : require . ExactArgs ( 1 ) ,
2024-03-11 17:13:34 -04:00
ValidArgsFunction : func ( _ * cobra . Command , args [ ] string , toComplete string ) ( [ ] string , cobra . ShellCompDirective ) {
2020-04-11 14:06:56 -04:00
if len ( args ) != 0 {
2024-08-17 10:00:23 -04:00
return noMoreArgsComp ( )
2020-04-11 14:06:56 -04:00
}
2021-03-13 16:28:37 -05:00
return compListReleases ( toComplete , args , cfg )
2020-04-11 14:06:56 -04:00
} ,
2022-01-22 18:17:09 -05:00
RunE : func ( _ * cobra . Command , args [ ] string ) ( returnError error ) {
2019-10-17 17:27:19 -04:00
client . Namespace = settings . Namespace ( )
2020-07-19 14:26:48 -04:00
notName := regexp . MustCompile ( ` ^!\s?name= ` )
for _ , f := range filter {
2025-08-14 07:27:39 -04:00
if after , ok := strings . CutPrefix ( f , "name=" ) ; ok {
client . Filters [ action . IncludeNameFilter ] = append ( client . Filters [ action . IncludeNameFilter ] , after )
2020-07-19 14:26:48 -04:00
} else if notName . MatchString ( f ) {
2022-02-17 10:26:07 -05:00
client . Filters [ action . ExcludeNameFilter ] = append ( client . Filters [ action . ExcludeNameFilter ] , notName . ReplaceAllLiteralString ( f , "" ) )
2020-07-19 14:26:48 -04:00
}
}
2022-01-22 18:17:09 -05:00
2022-01-22 17:20:18 -05:00
reli , shutdown , runErr := client . Run ( args [ 0 ] )
2022-01-22 18:17:09 -05:00
defer func ( ) {
if shutdownErr := shutdown ( ) ; shutdownErr != nil {
if returnError == nil {
returnError = shutdownErr
}
}
} ( )
2019-10-17 17:27:19 -04:00
// 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
// if requested
2025-10-08 17:57:55 -04:00
if runErr != nil && reli == nil {
2019-10-17 17:27:19 -04:00
return runErr
}
2025-10-08 17:57:55 -04:00
rel , err := releaserToV1Release ( reli )
if err != nil {
return err
}
2019-10-17 17:27:19 -04:00
2024-11-15 13:27:28 -05:00
if err := outfmt . Write ( out , & statusPrinter {
release : rel ,
debug : settings . Debug ,
showMetadata : false ,
2025-09-15 17:44:17 -04:00
hideNotes : true ,
2025-07-11 15:52:40 -04:00
noColor : settings . ShouldDisableColor ( ) ,
2024-11-15 13:27:28 -05:00
} ) ; err != nil {
2019-09-05 14:59:10 -04:00
return err
}
2019-10-17 17:27:19 -04:00
if outputLogs {
// Print a newline to stdout to separate the output
fmt . Fprintln ( out )
if err := client . GetPodLogs ( out , rel ) ; err != nil {
2025-06-10 18:15:26 -04:00
return errors . Join ( runErr , err )
2019-10-17 17:27:19 -04:00
}
}
return runErr
2019-09-05 13:23:20 -04:00
} ,
2017-01-04 10:13:26 -05:00
}
2019-09-05 13:23:20 -04:00
f := cmd . Flags ( )
f . DurationVar ( & client . Timeout , "timeout" , 300 * time . Second , "time to wait for any individual Kubernetes operation (like Jobs for hooks)" )
2020-04-13 14:05:33 -04:00
f . BoolVar ( & outputLogs , "logs" , false , "dump the logs from test pods (this runs after all tests are complete, but before any cleanup)" )
2020-07-19 14:26:48 -04:00
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)" )
2019-09-05 13:23:20 -04:00
2017-01-04 10:13:26 -05:00
return cmd
}