|
|
|
|
@ -27,6 +27,7 @@ import (
|
|
|
|
|
"net/url"
|
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"reflect"
|
|
|
|
|
"regexp"
|
|
|
|
|
"strings"
|
|
|
|
|
"testing"
|
|
|
|
|
@ -177,6 +178,67 @@ func installAction(t *testing.T) *Install {
|
|
|
|
|
return instAction
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type installCreateOptionRecorder struct {
|
|
|
|
|
*kubefake.FailingKubeClient
|
|
|
|
|
serverSideApply bool
|
|
|
|
|
forceConflicts bool
|
|
|
|
|
sawCreate bool
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *installCreateOptionRecorder) Create(resources kube.ResourceList, options ...kube.ClientCreateOption) (*kube.Result, error) {
|
|
|
|
|
serverSideApply, forceConflicts, err := parseCreateOptions(options)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
r.serverSideApply = serverSideApply
|
|
|
|
|
r.forceConflicts = forceConflicts
|
|
|
|
|
r.sawCreate = true
|
|
|
|
|
return r.FailingKubeClient.Create(resources, options...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseCreateOptions(options []kube.ClientCreateOption) (bool, bool, error) {
|
|
|
|
|
var serverSideApply bool
|
|
|
|
|
var forceConflicts bool
|
|
|
|
|
sawServerSideApply := false
|
|
|
|
|
sawForceConflicts := false
|
|
|
|
|
|
|
|
|
|
for _, option := range options {
|
|
|
|
|
fn := reflect.ValueOf(option)
|
|
|
|
|
if fn.Kind() != reflect.Func {
|
|
|
|
|
return false, false, fmt.Errorf("create option is not a function: %T", option)
|
|
|
|
|
}
|
|
|
|
|
argType := fn.Type().In(0)
|
|
|
|
|
if argType.Kind() != reflect.Ptr {
|
|
|
|
|
return false, false, fmt.Errorf("unexpected create option argument type: %s", argType)
|
|
|
|
|
}
|
|
|
|
|
arg := reflect.New(argType.Elem())
|
|
|
|
|
results := fn.Call([]reflect.Value{arg})
|
|
|
|
|
if len(results) > 0 && !results[0].IsNil() {
|
|
|
|
|
return false, false, results[0].Interface().(error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
serverSideApplyField := arg.Elem().FieldByName("serverSideApply")
|
|
|
|
|
if !serverSideApplyField.IsValid() {
|
|
|
|
|
return false, false, errors.New("client create options missing serverSideApply field")
|
|
|
|
|
}
|
|
|
|
|
forceConflictsField := arg.Elem().FieldByName("forceConflicts")
|
|
|
|
|
if !forceConflictsField.IsValid() {
|
|
|
|
|
return false, false, errors.New("client create options missing forceConflicts field")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
serverSideApply = serverSideApplyField.Bool()
|
|
|
|
|
forceConflicts = forceConflictsField.Bool()
|
|
|
|
|
sawServerSideApply = true
|
|
|
|
|
sawForceConflicts = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !sawServerSideApply || !sawForceConflicts {
|
|
|
|
|
return false, false, errors.New("expected server-side apply create options were not provided")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return serverSideApply, forceConflicts, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestInstallRelease(t *testing.T) {
|
|
|
|
|
is := assert.New(t)
|
|
|
|
|
req := require.New(t)
|
|
|
|
|
@ -220,6 +282,24 @@ func TestInstallRelease(t *testing.T) {
|
|
|
|
|
is.Equal(lrel.Info.Status, rcommon.StatusDeployed)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPerformInstallCreatePathPassesForceConflicts(t *testing.T) {
|
|
|
|
|
config := actionConfigFixtureWithDummyResources(t, nil)
|
|
|
|
|
baseClient := config.KubeClient.(*kubefake.FailingKubeClient)
|
|
|
|
|
recorder := &installCreateOptionRecorder{FailingKubeClient: baseClient}
|
|
|
|
|
config.KubeClient = recorder
|
|
|
|
|
|
|
|
|
|
instAction := installActionWithConfig(config)
|
|
|
|
|
instAction.DisableHooks = true
|
|
|
|
|
instAction.ServerSideApply = true
|
|
|
|
|
instAction.ForceConflicts = true
|
|
|
|
|
|
|
|
|
|
_, err := instAction.performInstall(releaseStub(), nil, createDummyResourceList(false))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.True(t, recorder.sawCreate, "expected performInstall to use the create path")
|
|
|
|
|
assert.True(t, recorder.serverSideApply)
|
|
|
|
|
assert.True(t, recorder.forceConflicts)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestInstallReleaseWithTakeOwnership_ResourceNotOwned(t *testing.T) {
|
|
|
|
|
// This test will test checking ownership of a resource
|
|
|
|
|
// returned by the fake client. If the resource is not
|
|
|
|
|
|