@ -19,7 +19,6 @@ package action
import (
import (
"bytes"
"bytes"
"context"
"context"
"errors"
"fmt"
"fmt"
"io"
"io"
"io/fs"
"io/fs"
@ -137,21 +136,21 @@ func TestInstallRelease(t *testing.T) {
if err != nil {
if err != nil {
t . Fatalf ( "Failed install: %s" , err )
t . Fatalf ( "Failed install: %s" , err )
}
}
is . Equal ( res . Name , "test-install-release" , "Expected release name." )
is . Equal ( "test-install-release" , res . Name , "Expected release name." )
is . Equal ( res . Namespace , "spaced" )
is . Equal ( "spaced" , res . Namespace )
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
is . NoError ( err )
req . NoError ( err )
is . Len ( rel . Hooks , 1 )
is . Len ( rel . Hooks , 1 )
is . Equal ( rel . Hooks [ 0 ] . Manifest , manifestWithHook )
is . Equal ( rel . Hooks [ 0 ] . Manifest , manifestWithHook )
is . Equal ( rel . Hooks [ 0 ] . Events [ 0 ] , release . HookPostInstall )
is . Equal ( rel ease. HookPostInstall , rel . Hooks [ 0 ] . Events [ 0 ] )
is . Equal ( rel . Hooks [ 0 ] . Events [ 1 ] , release . HookPreDelete , "Expected event 0 is pre-delete" )
is . Equal ( rel ease. HookPreDelete , rel . Hooks [ 0 ] . Events [ 1 ] , "Expected event 0 is pre-delete" )
is . NotE qual( len ( res . Manifest ) , 0 )
is . NotE mpty ( res . Manifest )
is . NotE qual( len ( rel . Manifest ) , 0 )
is . NotE mpty ( rel . Manifest )
is . Contains ( rel . Manifest , "---\n# Source: hello/templates/hello\nhello: world" )
is . Contains ( rel . Manifest , "---\n# Source: hello/templates/hello\nhello: world" )
is . Equal ( rel . Info . Description , "Install complete" )
is . Equal ( "Install complete" , rel . Info . Description )
// Detecting previous bug where context termination after successful release
// Detecting previous bug where context termination after successful release
// caused release to fail.
// caused release to fail.
@ -159,7 +158,7 @@ func TestInstallRelease(t *testing.T) {
time . Sleep ( time . Millisecond * 100 )
time . Sleep ( time . Millisecond * 100 )
lastRelease , err := instAction . cfg . Releases . Last ( rel . Name )
lastRelease , err := instAction . cfg . Releases . Last ( rel . Name )
req . NoError ( err )
req . NoError ( err )
is . Equal ( lastRelease. Info . Status , release . StatusDeployed )
is . Equal ( release. StatusDeployed , lastRelease . Info . Status )
}
}
func TestInstallReleaseWithTakeOwnership_ResourceNotOwned ( t * testing . T ) {
func TestInstallReleaseWithTakeOwnership_ResourceNotOwned ( t * testing . T ) {
@ -173,6 +172,7 @@ func TestInstallReleaseWithTakeOwnership_ResourceNotOwned(t *testing.T) {
// "Client{Namespace: namespace, kubeClient: k8sfake.NewClientset()}"
// "Client{Namespace: namespace, kubeClient: k8sfake.NewClientset()}"
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
// Resource list from cluster is NOT owned by helm chart
// Resource list from cluster is NOT owned by helm chart
config := actionConfigFixtureWithDummyResources ( t , createDummyResourceList ( false ) )
config := actionConfigFixtureWithDummyResources ( t , createDummyResourceList ( false ) )
@ -184,13 +184,14 @@ func TestInstallReleaseWithTakeOwnership_ResourceNotOwned(t *testing.T) {
}
}
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
is . NoError ( err )
req . NoError ( err )
is . Equal ( rel . Info . Description , "Install complete" )
is . Equal ( "Install complete" , rel . Info . Description )
}
}
func TestInstallReleaseWithTakeOwnership_ResourceOwned ( t * testing . T ) {
func TestInstallReleaseWithTakeOwnership_ResourceOwned ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
// Resource list from cluster is owned by helm chart
// Resource list from cluster is owned by helm chart
config := actionConfigFixtureWithDummyResources ( t , createDummyResourceList ( true ) )
config := actionConfigFixtureWithDummyResources ( t , createDummyResourceList ( true ) )
@ -201,9 +202,9 @@ func TestInstallReleaseWithTakeOwnership_ResourceOwned(t *testing.T) {
t . Fatalf ( "Failed install: %s" , err )
t . Fatalf ( "Failed install: %s" , err )
}
}
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
is . NoError ( err )
req . NoError ( err )
is . Equal ( rel . Info . Description , "Install complete" )
is . Equal ( "Install complete" , rel . Info . Description )
}
}
func TestInstallReleaseWithTakeOwnership_ResourceOwnedNoFlag ( t * testing . T ) {
func TestInstallReleaseWithTakeOwnership_ResourceOwnedNoFlag ( t * testing . T ) {
@ -213,12 +214,12 @@ func TestInstallReleaseWithTakeOwnership_ResourceOwnedNoFlag(t *testing.T) {
config := actionConfigFixtureWithDummyResources ( t , createDummyResourceList ( false ) )
config := actionConfigFixtureWithDummyResources ( t , createDummyResourceList ( false ) )
instAction := installActionWithConfig ( config )
instAction := installActionWithConfig ( config )
_ , err := instAction . Run ( buildChart ( ) , nil )
_ , err := instAction . Run ( buildChart ( ) , nil )
is . Error ( err )
is . ErrorContains ( err , "unable to continue with install" )
is . Contains ( err . Error ( ) , "unable to continue with install" )
}
}
func TestInstallReleaseWithValues ( t * testing . T ) {
func TestInstallReleaseWithValues ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
userVals := map [ string ] interface { } {
userVals := map [ string ] interface { } {
"nestedKey" : map [ string ] interface { } {
"nestedKey" : map [ string ] interface { } {
@ -234,19 +235,19 @@ func TestInstallReleaseWithValues(t *testing.T) {
if err != nil {
if err != nil {
t . Fatalf ( "Failed install: %s" , err )
t . Fatalf ( "Failed install: %s" , err )
}
}
is . Equal ( res . Name , "test-install-release" , "Expected release name." )
is . Equal ( "test-install-release" , res . Name , "Expected release name." )
is . Equal ( res . Namespace , "spaced" )
is . Equal ( "spaced" , res . Namespace )
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
is . NoError ( err )
req . NoError ( err )
is . Len ( rel . Hooks , 1 )
is . Len ( rel . Hooks , 1 )
is . Equal ( rel . Hooks [ 0 ] . Manifest , manifestWithHook )
is . Equal ( rel . Hooks [ 0 ] . Manifest , manifestWithHook )
is . Equal ( rel . Hooks [ 0 ] . Events [ 0 ] , release . HookPostInstall )
is . Equal ( rel ease. HookPostInstall , rel . Hooks [ 0 ] . Events [ 0 ] )
is . Equal ( rel . Hooks [ 0 ] . Events [ 1 ] , release . HookPreDelete , "Expected event 0 is pre-delete" )
is . Equal ( rel ease. HookPreDelete , rel . Hooks [ 0 ] . Events [ 1 ] , "Expected event 0 is pre-delete" )
is . NotE qual( len ( res . Manifest ) , 0 )
is . NotE mpty ( res . Manifest )
is . NotE qual( len ( rel . Manifest ) , 0 )
is . NotE mpty ( rel . Manifest )
is . Contains ( rel . Manifest , "---\n# Source: hello/templates/hello\nhello: world" )
is . Contains ( rel . Manifest , "---\n# Source: hello/templates/hello\nhello: world" )
is . Equal ( "Install complete" , rel . Info . Description )
is . Equal ( "Install complete" , rel . Info . Description )
is . Equal ( expectedUserValues , rel . Config )
is . Equal ( expectedUserValues , rel . Config )
@ -259,7 +260,7 @@ func TestInstallReleaseClientOnly(t *testing.T) {
instAction . Run ( buildChart ( ) , nil ) // disregard output
instAction . Run ( buildChart ( ) , nil ) // disregard output
is . Equal ( instAction . cfg . Capabilities , chartutil . DefaultCapabilities )
is . Equal ( instAction . cfg . Capabilities , chartutil . DefaultCapabilities )
is . Equal ( instAction . cfg . KubeClient , & kubefake . PrintingKubeClient { Out : io . Discard } )
is . Equal ( & kubefake . PrintingKubeClient { Out : io . Discard } , instAction . cfg . KubeClient )
}
}
func TestInstallRelease_NoName ( t * testing . T ) {
func TestInstallRelease_NoName ( t * testing . T ) {
@ -270,11 +271,12 @@ func TestInstallRelease_NoName(t *testing.T) {
if err == nil {
if err == nil {
t . Fatal ( "expected failure when no name is specified" )
t . Fatal ( "expected failure when no name is specified" )
}
}
assert . Contains( t , err . Error ( ) , "no name provided" )
assert . Error Contains( t , err , "no name provided" )
}
}
func TestInstallRelease_WithNotes ( t * testing . T ) {
func TestInstallRelease_WithNotes ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
instAction . ReleaseName = "with-notes"
instAction . ReleaseName = "with-notes"
vals := map [ string ] interface { } { }
vals := map [ string ] interface { } { }
@ -283,25 +285,26 @@ func TestInstallRelease_WithNotes(t *testing.T) {
t . Fatalf ( "Failed install: %s" , err )
t . Fatalf ( "Failed install: %s" , err )
}
}
is . Equal ( res . Name , "with-notes" )
is . Equal ( "with-notes" , res . Name )
is . Equal ( res . Namespace , "spaced" )
is . Equal ( "spaced" , res . Namespace )
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
is . NoError ( err )
req . NoError ( err )
is . Len ( rel . Hooks , 1 )
is . Len ( rel . Hooks , 1 )
is . Equal ( rel . Hooks [ 0 ] . Manifest , manifestWithHook )
is . Equal ( rel . Hooks [ 0 ] . Manifest , manifestWithHook )
is . Equal ( rel . Hooks [ 0 ] . Events [ 0 ] , release . HookPostInstall )
is . Equal ( rel ease. HookPostInstall , rel . Hooks [ 0 ] . Events [ 0 ] )
is . Equal ( rel . Hooks [ 0 ] . Events [ 1 ] , release . HookPreDelete , "Expected event 0 is pre-delete" )
is . Equal ( rel ease. HookPreDelete , rel . Hooks [ 0 ] . Events [ 1 ] , "Expected event 0 is pre-delete" )
is . NotE qual( len ( res . Manifest ) , 0 )
is . NotE mpty ( res . Manifest )
is . NotE qual( len ( rel . Manifest ) , 0 )
is . NotE mpty ( rel . Manifest )
is . Contains ( rel . Manifest , "---\n# Source: hello/templates/hello\nhello: world" )
is . Contains ( rel . Manifest , "---\n# Source: hello/templates/hello\nhello: world" )
is . Equal ( rel . Info . Description , "Install complete" )
is . Equal ( "Install complete" , rel . Info . Description )
is . Equal ( rel . Info . Notes , "note here" )
is . Equal ( "note here" , rel . Info . Notes )
}
}
func TestInstallRelease_WithNotesRendered ( t * testing . T ) {
func TestInstallRelease_WithNotesRendered ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
instAction . ReleaseName = "with-notes"
instAction . ReleaseName = "with-notes"
vals := map [ string ] interface { } { }
vals := map [ string ] interface { } { }
@ -311,16 +314,17 @@ func TestInstallRelease_WithNotesRendered(t *testing.T) {
}
}
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
is . NoError ( err )
req . NoError ( err )
expectedNotes := fmt . Sprintf ( "got-%s" , res . Name )
expectedNotes := fmt . Sprintf ( "got-%s" , res . Name )
is . Equal ( expectedNotes , rel . Info . Notes )
is . Equal ( expectedNotes , rel . Info . Notes )
is . Equal ( rel . Info . Description , "Install complete" )
is . Equal ( "Install complete" , rel . Info . Description )
}
}
func TestInstallRelease_WithChartAndDependencyParentNotes ( t * testing . T ) {
func TestInstallRelease_WithChartAndDependencyParentNotes ( t * testing . T ) {
// Regression: Make sure that the child's notes don't override the parent's
// Regression: Make sure that the child's notes don't override the parent's
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
instAction . ReleaseName = "with-notes"
instAction . ReleaseName = "with-notes"
vals := map [ string ] interface { } { }
vals := map [ string ] interface { } { }
@ -331,14 +335,15 @@ func TestInstallRelease_WithChartAndDependencyParentNotes(t *testing.T) {
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
is . Equal ( "with-notes" , rel . Name )
is . Equal ( "with-notes" , rel . Name )
is . NoError ( err )
req . NoError ( err )
is . Equal ( "parent" , rel . Info . Notes )
is . Equal ( "parent" , rel . Info . Notes )
is . Equal ( rel . Info . Description , "Install complete" )
is . Equal ( "Install complete" , rel . Info . Description )
}
}
func TestInstallRelease_WithChartAndDependencyAllNotes ( t * testing . T ) {
func TestInstallRelease_WithChartAndDependencyAllNotes ( t * testing . T ) {
// Regression: Make sure that the child's notes don't override the parent's
// Regression: Make sure that the child's notes don't override the parent's
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
instAction . ReleaseName = "with-notes"
instAction . ReleaseName = "with-notes"
instAction . SubNotes = true
instAction . SubNotes = true
@ -350,16 +355,17 @@ func TestInstallRelease_WithChartAndDependencyAllNotes(t *testing.T) {
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
rel , err := instAction . cfg . Releases . Get ( res . Name , res . Version )
is . Equal ( "with-notes" , rel . Name )
is . Equal ( "with-notes" , rel . Name )
is . NoError ( err )
req . NoError ( err )
// test run can return as either 'parent\nchild' or 'child\nparent'
// test run can return as either 'parent\nchild' or 'child\nparent'
if ! strings . Contains ( rel . Info . Notes , "parent" ) && ! strings . Contains ( rel . Info . Notes , "child" ) {
if ! strings . Contains ( rel . Info . Notes , "parent" ) && ! strings . Contains ( rel . Info . Notes , "child" ) {
t . Fatalf ( "Expected 'parent\nchild' or 'child\nparent', got '%s'" , rel . Info . Notes )
t . Fatalf ( "Expected 'parent\nchild' or 'child\nparent', got '%s'" , rel . Info . Notes )
}
}
is . Equal ( rel . Info . Description , "Install complete" )
is . Equal ( "Install complete" , rel . Info . Description )
}
}
func TestInstallRelease_DryRun ( t * testing . T ) {
func TestInstallRelease_DryRun ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
instAction . DryRun = true
instAction . DryRun = true
vals := map [ string ] interface { } { }
vals := map [ string ] interface { } { }
@ -375,14 +381,15 @@ func TestInstallRelease_DryRun(t *testing.T) {
is . NotContains ( res . Manifest , "empty" )
is . NotContains ( res . Manifest , "empty" )
_ , err = instAction . cfg . Releases . Get ( res . Name , res . Version )
_ , err = instAction . cfg . Releases . Get ( res . Name , res . Version )
is . Error ( err )
req . Error ( err )
is . Len ( res . Hooks , 1 )
is . Len ( res . Hooks , 1 )
is . True ( res . Hooks [ 0 ] . LastRun . CompletedAt . IsZero ( ) , "expect hook to not be marked as run" )
is . True ( res . Hooks [ 0 ] . LastRun . CompletedAt . IsZero ( ) , "expect hook to not be marked as run" )
is . Equal ( res . Info . Description , "Dry run complete" )
is . Equal ( "Dry run complete" , res . Info . Description )
}
}
func TestInstallRelease_DryRunHiddenSecret ( t * testing . T ) {
func TestInstallRelease_DryRunHiddenSecret ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
// First perform a normal dry-run with the secret and confirm its presence.
// First perform a normal dry-run with the secret and confirm its presence.
@ -395,8 +402,8 @@ func TestInstallRelease_DryRunHiddenSecret(t *testing.T) {
is . Contains ( res . Manifest , "---\n# Source: hello/templates/secret.yaml\napiVersion: v1\nkind: Secret" )
is . Contains ( res . Manifest , "---\n# Source: hello/templates/secret.yaml\napiVersion: v1\nkind: Secret" )
_ , err = instAction . cfg . Releases . Get ( res . Name , res . Version )
_ , err = instAction . cfg . Releases . Get ( res . Name , res . Version )
is . Error ( err )
req . Error ( err )
is . Equal ( res . Info . Description , "Dry run complete" )
is . Equal ( "Dry run complete" , res . Info . Description )
// Perform a dry-run where the secret should not be present
// Perform a dry-run where the secret should not be present
instAction . HideSecret = true
instAction . HideSecret = true
@ -409,8 +416,8 @@ func TestInstallRelease_DryRunHiddenSecret(t *testing.T) {
is . NotContains ( res2 . Manifest , "---\n# Source: hello/templates/secret.yaml\napiVersion: v1\nkind: Secret" )
is . NotContains ( res2 . Manifest , "---\n# Source: hello/templates/secret.yaml\napiVersion: v1\nkind: Secret" )
_ , err = instAction . cfg . Releases . Get ( res2 . Name , res2 . Version )
_ , err = instAction . cfg . Releases . Get ( res2 . Name , res2 . Version )
is . Error ( err )
req . Error ( err )
is . Equal ( res2 . Info . Description , "Dry run complete" )
is . Equal ( "Dry run complete" , res2 . Info . Description )
// Ensure there is an error when HideSecret True but not in a dry-run mode
// Ensure there is an error when HideSecret True but not in a dry-run mode
instAction . DryRun = false
instAction . DryRun = false
@ -455,7 +462,7 @@ func TestInstallReleaseIncorrectTemplate_DryRun(t *testing.T) {
t . Fatalf ( "Install should fail containing error: %s" , expectedErr )
t . Fatalf ( "Install should fail containing error: %s" , expectedErr )
}
}
if err != nil {
if err != nil {
is . Contains( err . Error ( ) , expectedErr )
is . Error Contains( err , expectedErr )
}
}
}
}
@ -477,6 +484,7 @@ func TestInstallRelease_NoHooks(t *testing.T) {
func TestInstallRelease_FailedHooks ( t * testing . T ) {
func TestInstallRelease_FailedHooks ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
instAction . ReleaseName = "failed-hooks"
instAction . ReleaseName = "failed-hooks"
failer := instAction . cfg . KubeClient . ( * kubefake . FailingKubeClient )
failer := instAction . cfg . KubeClient . ( * kubefake . FailingKubeClient )
@ -487,14 +495,15 @@ func TestInstallRelease_FailedHooks(t *testing.T) {
vals := map [ string ] interface { } { }
vals := map [ string ] interface { } { }
res , err := instAction . Run ( buildChart ( ) , vals )
res , err := instAction . Run ( buildChart ( ) , vals )
is . Error ( err )
req . Error ( err )
is . Contains ( res . Info . Description , "failed post-install" )
is . Contains ( res . Info . Description , "failed post-install" )
is . E qual( "" , outBuffer . String ( ) )
is . E mpty( outBuffer . String ( ) )
is . Equal ( release . StatusFailed , res . Info . Status )
is . Equal ( release . StatusFailed , res . Info . Status )
}
}
func TestInstallRelease_ReplaceRelease ( t * testing . T ) {
func TestInstallRelease_ReplaceRelease ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
instAction . Replace = true
instAction . Replace = true
@ -505,34 +514,35 @@ func TestInstallRelease_ReplaceRelease(t *testing.T) {
vals := map [ string ] interface { } { }
vals := map [ string ] interface { } { }
res , err := instAction . Run ( buildChart ( ) , vals )
res , err := instAction . Run ( buildChart ( ) , vals )
is . NoError ( err )
req . NoError ( err )
// This should have been auto-incremented
// This should have been auto-incremented
is . Equal ( 2 , res . Version )
is . Equal ( 2 , res . Version )
is . Equal ( res . Name , rel . Name )
is . Equal ( res . Name , rel . Name )
getres , err := instAction . cfg . Releases . Get ( rel . Name , res . Version )
getres , err := instAction . cfg . Releases . Get ( rel . Name , res . Version )
is . NoError ( err )
req . NoError ( err )
is . Equal ( getres. Info . Status , release . StatusDeployed )
is . Equal ( release. StatusDeployed , getres . Info . Status )
}
}
func TestInstallRelease_KubeVersion ( t * testing . T ) {
func TestInstallRelease_KubeVersion ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
vals := map [ string ] interface { } { }
vals := map [ string ] interface { } { }
_ , err := instAction . Run ( buildChart ( withKube ( ">=0.0.0" ) ) , vals )
_ , err := instAction . Run ( buildChart ( withKube ( ">=0.0.0" ) ) , vals )
is . NoError ( err )
req . NoError ( err )
// This should fail for a few hundred years
// This should fail for a few hundred years
instAction . ReleaseName = "should-fail"
instAction . ReleaseName = "should-fail"
vals = map [ string ] interface { } { }
vals = map [ string ] interface { } { }
_ , err = instAction . Run ( buildChart ( withKube ( ">=99.0.0" ) ) , vals )
_ , err = instAction . Run ( buildChart ( withKube ( ">=99.0.0" ) ) , vals )
is . Error ( err )
is . ErrorContains ( err , "chart requires kubeVersion" )
is . Contains ( err . Error ( ) , "chart requires kubeVersion" )
}
}
func TestInstallRelease_Wait ( t * testing . T ) {
func TestInstallRelease_Wait ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
instAction . ReleaseName = "come-fail-away"
instAction . ReleaseName = "come-fail-away"
failer := instAction . cfg . KubeClient . ( * kubefake . FailingKubeClient )
failer := instAction . cfg . KubeClient . ( * kubefake . FailingKubeClient )
@ -544,14 +554,16 @@ func TestInstallRelease_Wait(t *testing.T) {
goroutines := runtime . NumGoroutine ( )
goroutines := runtime . NumGoroutine ( )
res , err := instAction . Run ( buildChart ( ) , vals )
res , err := instAction . Run ( buildChart ( ) , vals )
is . Error ( err )
req . Error ( err )
is . Contains ( res . Info . Description , "I timed out" )
is . Contains ( res . Info . Description , "I timed out" )
is . Equal ( re s. Info . Status , release . StatusFailed )
is . Equal ( re lease. StatusFailed , res . Info . Status )
is . Equal ( goroutines , runtime . NumGoroutine ( ) )
is . Equal ( goroutines , runtime . NumGoroutine ( ) )
}
}
func TestInstallRelease_Wait_Interrupted ( t * testing . T ) {
func TestInstallRelease_Wait_Interrupted ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
instAction . ReleaseName = "interrupted-release"
instAction . ReleaseName = "interrupted-release"
failer := instAction . cfg . KubeClient . ( * kubefake . FailingKubeClient )
failer := instAction . cfg . KubeClient . ( * kubefake . FailingKubeClient )
@ -566,15 +578,16 @@ func TestInstallRelease_Wait_Interrupted(t *testing.T) {
goroutines := runtime . NumGoroutine ( )
goroutines := runtime . NumGoroutine ( )
_ , err := instAction . RunWithContext ( ctx , buildChart ( ) , vals )
_ , err := instAction . RunWithContext ( ctx , buildChart ( ) , vals )
is . Error ( err )
req . ErrorContains ( err , "context canceled" )
is . Contains ( err . Error ( ) , "context canceled" )
is . Equal ( goroutines + 1 , runtime . NumGoroutine ( ) ) // installation goroutine still is in background
is . Equal ( goroutines + 1 , runtime . NumGoroutine ( ) ) // installation goroutine still is in background
time . Sleep ( 10 * time . Second ) // wait for goroutine to finish
time . Sleep ( 10 * time . Second ) // wait for goroutine to finish
is . Equal ( goroutines , runtime . NumGoroutine ( ) )
is . Equal ( goroutines , runtime . NumGoroutine ( ) )
}
}
func TestInstallRelease_WaitForJobs ( t * testing . T ) {
func TestInstallRelease_WaitForJobs ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
instAction . ReleaseName = "come-fail-away"
instAction . ReleaseName = "come-fail-away"
failer := instAction . cfg . KubeClient . ( * kubefake . FailingKubeClient )
failer := instAction . cfg . KubeClient . ( * kubefake . FailingKubeClient )
@ -585,13 +598,14 @@ func TestInstallRelease_WaitForJobs(t *testing.T) {
vals := map [ string ] interface { } { }
vals := map [ string ] interface { } { }
res , err := instAction . Run ( buildChart ( ) , vals )
res , err := instAction . Run ( buildChart ( ) , vals )
is . Error ( err )
req . Error ( err )
is . Contains ( res . Info . Description , "I timed out" )
is . Contains ( res . Info . Description , "I timed out" )
is . Equal ( re s. Info . Status , release . StatusFailed )
is . Equal ( re lease. StatusFailed , res . Info . Status )
}
}
func TestInstallRelease_Atomic ( t * testing . T ) {
func TestInstallRelease_Atomic ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
t . Run ( "atomic uninstall succeeds" , func ( t * testing . T ) {
t . Run ( "atomic uninstall succeeds" , func ( t * testing . T ) {
instAction := installAction ( t )
instAction := installAction ( t )
@ -606,13 +620,12 @@ func TestInstallRelease_Atomic(t *testing.T) {
vals := map [ string ] interface { } { }
vals := map [ string ] interface { } { }
res , err := instAction . Run ( buildChart ( ) , vals )
res , err := instAction . Run ( buildChart ( ) , vals )
is . Error ( err )
req . ErrorContains ( err , "I timed out" )
is . Contains ( err . Error ( ) , "I timed out" )
req . ErrorContains ( err , "atomic" )
is . Contains ( err . Error ( ) , "atomic" )
// Now make sure it isn't in storage anymore
// Now make sure it isn't in storage anymore
_ , err = instAction . cfg . Releases . Get ( res . Name , res . Version )
_ , err = instAction . cfg . Releases . Get ( res . Name , res . Version )
is . Error ( err )
req . Error ( err )
is . Equal ( err , driver . ErrReleaseNotFound )
is . Equal ( err , driver . ErrReleaseNotFound )
} )
} )
@ -627,15 +640,15 @@ func TestInstallRelease_Atomic(t *testing.T) {
vals := map [ string ] interface { } { }
vals := map [ string ] interface { } { }
_ , err := instAction . Run ( buildChart ( ) , vals )
_ , err := instAction . Run ( buildChart ( ) , vals )
is . Error ( err )
req . ErrorContains ( err , "I timed out" )
is . Contains ( err . Error ( ) , "I timed out" )
req . ErrorContains ( err , "uninstall fail" )
is . Contains ( err . Error ( ) , "uninstall fail" )
is . ErrorContains ( err , "an error occurred while uninstalling the release" )
is . Contains ( err . Error ( ) , "an error occurred while uninstalling the release" )
} )
} )
}
}
func TestInstallRelease_Atomic_Interrupted ( t * testing . T ) {
func TestInstallRelease_Atomic_Interrupted ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
instAction . ReleaseName = "interrupted-release"
instAction . ReleaseName = "interrupted-release"
failer := instAction . cfg . KubeClient . ( * kubefake . FailingKubeClient )
failer := instAction . cfg . KubeClient . ( * kubefake . FailingKubeClient )
@ -650,20 +663,19 @@ func TestInstallRelease_Atomic_Interrupted(t *testing.T) {
goroutines := runtime . NumGoroutine ( )
goroutines := runtime . NumGoroutine ( )
res , err := instAction . RunWithContext ( ctx , buildChart ( ) , vals )
res , err := instAction . RunWithContext ( ctx , buildChart ( ) , vals )
is . Error ( err )
req . ErrorContains ( err , "context canceled" )
is . Contains ( err . Error ( ) , "context canceled" )
req . ErrorContains ( err , "atomic" )
is . Contains ( err . Error ( ) , "atomic" )
req . ErrorContains ( err , "uninstalled" )
is . Contains ( err . Error ( ) , "uninstalled" )
// Now make sure it isn't in storage anymore
// Now make sure it isn't in storage anymore
_ , err = instAction . cfg . Releases . Get ( res . Name , res . Version )
_ , err = instAction . cfg . Releases . Get ( res . Name , res . Version )
is . Error ( err )
req . Error ( err )
is . Equal ( err , driver . ErrReleaseNotFound )
is . Equal ( err , driver . ErrReleaseNotFound )
is . Equal ( goroutines + 1 , runtime . NumGoroutine ( ) ) // installation goroutine still is in background
is . Equal ( goroutines + 1 , runtime . NumGoroutine ( ) ) // installation goroutine still is in background
time . Sleep ( 10 * time . Second ) // wait for goroutine to finish
time . Sleep ( 10 * time . Second ) // wait for goroutine to finish
is . Equal ( goroutines , runtime . NumGoroutine ( ) )
is . Equal ( goroutines , runtime . NumGoroutine ( ) )
}
}
func TestNameTemplate ( t * testing . T ) {
func TestNameTemplate ( t * testing . T ) {
testCases := [ ] nameTemplateTestCase {
testCases := [ ] nameTemplateTestCase {
// Just a straight up nop please
// Just a straight up nop please
@ -735,6 +747,7 @@ func TestNameTemplate(t *testing.T) {
func TestInstallReleaseOutputDir ( t * testing . T ) {
func TestInstallReleaseOutputDir ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
vals := map [ string ] interface { } { }
vals := map [ string ] interface { } { }
@ -748,25 +761,26 @@ func TestInstallReleaseOutputDir(t *testing.T) {
}
}
_ , err = os . Stat ( filepath . Join ( dir , "hello/templates/goodbye" ) )
_ , err = os . Stat ( filepath . Join ( dir , "hello/templates/goodbye" ) )
is . NoError ( err )
req . NoError ( err )
_ , err = os . Stat ( filepath . Join ( dir , "hello/templates/hello" ) )
_ , err = os . Stat ( filepath . Join ( dir , "hello/templates/hello" ) )
is . NoError ( err )
req . NoError ( err )
_ , err = os . Stat ( filepath . Join ( dir , "hello/templates/with-partials" ) )
_ , err = os . Stat ( filepath . Join ( dir , "hello/templates/with-partials" ) )
is . NoError ( err )
req . NoError ( err )
_ , err = os . Stat ( filepath . Join ( dir , "hello/templates/rbac" ) )
_ , err = os . Stat ( filepath . Join ( dir , "hello/templates/rbac" ) )
is . NoError ( err )
req . NoError ( err )
test . AssertGoldenFile ( t , filepath . Join ( dir , "hello/templates/rbac" ) , "rbac.txt" )
test . AssertGoldenFile ( t , filepath . Join ( dir , "hello/templates/rbac" ) , "rbac.txt" )
_ , err = os . Stat ( filepath . Join ( dir , "hello/templates/empty" ) )
_ , err = os . Stat ( filepath . Join ( dir , "hello/templates/empty" ) )
is . True( errors . Is( err , fs . ErrNotExist ) )
is . Error Is( err , fs . ErrNotExist )
}
}
func TestInstallOutputDirWithReleaseName ( t * testing . T ) {
func TestInstallOutputDirWithReleaseName ( t * testing . T ) {
is := assert . New ( t )
is := assert . New ( t )
req := require . New ( t )
instAction := installAction ( t )
instAction := installAction ( t )
vals := map [ string ] interface { } { }
vals := map [ string ] interface { } { }
@ -784,21 +798,21 @@ func TestInstallOutputDirWithReleaseName(t *testing.T) {
}
}
_ , err = os . Stat ( filepath . Join ( newDir , "hello/templates/goodbye" ) )
_ , err = os . Stat ( filepath . Join ( newDir , "hello/templates/goodbye" ) )
is . NoError ( err )
req . NoError ( err )
_ , err = os . Stat ( filepath . Join ( newDir , "hello/templates/hello" ) )
_ , err = os . Stat ( filepath . Join ( newDir , "hello/templates/hello" ) )
is . NoError ( err )
req . NoError ( err )
_ , err = os . Stat ( filepath . Join ( newDir , "hello/templates/with-partials" ) )
_ , err = os . Stat ( filepath . Join ( newDir , "hello/templates/with-partials" ) )
is . NoError ( err )
req . NoError ( err )
_ , err = os . Stat ( filepath . Join ( newDir , "hello/templates/rbac" ) )
_ , err = os . Stat ( filepath . Join ( newDir , "hello/templates/rbac" ) )
is . NoError ( err )
req . NoError ( err )
test . AssertGoldenFile ( t , filepath . Join ( newDir , "hello/templates/rbac" ) , "rbac.txt" )
test . AssertGoldenFile ( t , filepath . Join ( newDir , "hello/templates/rbac" ) , "rbac.txt" )
_ , err = os . Stat ( filepath . Join ( newDir , "hello/templates/empty" ) )
_ , err = os . Stat ( filepath . Join ( newDir , "hello/templates/empty" ) )
is . True( errors . Is( err , fs . ErrNotExist ) )
is . Error Is( err , fs . ErrNotExist )
}
}
func TestNameAndChart ( t * testing . T ) {
func TestNameAndChart ( t * testing . T ) {