mirror of
https://github.com/hanzoai/cd.git
synced 2026-10-30 14:56:45 +00:00
go fix applied the modernizers: promoted-field keys in struct literals,
strings.Cut, SplitSeq, new(expr), slices and maps helpers, wg.Go, reflect.TypeFor
and errors.AsType. omitzero is left out, since omitting a zero struct such as
time.Time{} is a per-field wire decision and not a mechanical one.
Two changes the modernizers could not make for themselves. AsType needs its type
argument to be an error, so the git exit-status reader embeds error in the
interface it asks for. And an error built by concatenating a tag list into its
own format string now says so with a verb, which is what vet was pointing at.
Co-authored-by: Hanzo Dev <[email protected]>
550 lines
18 KiB
Go
550 lines
18 KiB
Go
package kube
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
"github.com/go-logr/logr"
|
|
"github.com/hanzoai/cd/gitops-engine/pkg/utils/kube/mocks"
|
|
testingutils "github.com/hanzoai/cd/gitops-engine/pkg/utils/testing"
|
|
"github.com/hanzoai/cd/gitops-engine/pkg/utils/tracing"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
"github.com/stretchr/testify/require"
|
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
|
"k8s.io/cli-runtime/pkg/printers"
|
|
"k8s.io/client-go/kubernetes"
|
|
kubefake "k8s.io/client-go/kubernetes/fake"
|
|
"k8s.io/client-go/rest"
|
|
"k8s.io/kubectl/pkg/cmd/apply"
|
|
"k8s.io/kubectl/pkg/cmd/create"
|
|
"k8s.io/kubectl/pkg/cmd/replace"
|
|
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
|
)
|
|
|
|
func newTestKubectlResourceOperations(t *testing.T) (*kubectlResourceOperations, *mocks.KubectlOptionsRunner) {
|
|
t.Helper()
|
|
|
|
cmdMocks := mocks.NewKubectlOptionsRunner(t)
|
|
|
|
k := &kubectlResourceOperations{
|
|
config: &rest.Config{},
|
|
log: logr.Discard(),
|
|
tracer: &tracing.NopTracer{},
|
|
fact: cmdutil.NewFactory(cmdutil.NewMatchVersionFlags(genericclioptions.NewConfigFlags(true))),
|
|
optionsRunner: cmdMocks,
|
|
getClientFunc: func() (kubernetes.Interface, error) {
|
|
return kubefake.NewSimpleClientset(), nil
|
|
},
|
|
outputMode: outputModeLog,
|
|
}
|
|
return k, cmdMocks
|
|
}
|
|
|
|
func TestAuthReconcileWithMissingNamespace(t *testing.T) {
|
|
t.Parallel()
|
|
namespace := "test-ns"
|
|
|
|
t.Run("Namespaced resources", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, _ := newTestKubectlResourceOperations(t)
|
|
|
|
role := testingutils.NewRole()
|
|
role.SetNamespace(namespace)
|
|
|
|
_, err := k.rbacReconcile(t.Context(), role, cmdutil.DryRunNone)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), `namespaces "test-ns" not found`)
|
|
|
|
roleBinding := testingutils.NewRoleBinding()
|
|
roleBinding.SetNamespace(namespace)
|
|
|
|
_, err = k.rbacReconcile(t.Context(), roleBinding, cmdutil.DryRunNone)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), `namespaces "test-ns" not found`)
|
|
})
|
|
|
|
t.Run("Cluster-scoped resources", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
cmdMocks.On("AuthReconcile", mock.Anything).Return(nil).Twice()
|
|
|
|
clusterRole := testingutils.NewClusterRole()
|
|
clusterRole.SetNamespace(namespace)
|
|
|
|
_, err := k.rbacReconcile(t.Context(), clusterRole, cmdutil.DryRunNone)
|
|
require.NoError(t, err)
|
|
|
|
clusterRoleBinding := testingutils.NewClusterRoleBinding()
|
|
clusterRoleBinding.SetNamespace(namespace)
|
|
|
|
_, err = k.rbacReconcile(t.Context(), clusterRoleBinding, cmdutil.DryRunNone)
|
|
require.NoError(t, err)
|
|
})
|
|
}
|
|
|
|
func TestAuthReconcileUsage(t *testing.T) {
|
|
t.Parallel()
|
|
// This test verifies that the rbacReconcile logic is correctly applied based on the operation type
|
|
// and server-side apply setting.
|
|
|
|
role := testingutils.NewRole()
|
|
|
|
t.Run("CreateResource should not call auth reconcile", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
cmdMocks.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
|
|
|
_, err := k.CreateResource(t.Context(), role, cmdutil.DryRunNone, false)
|
|
require.NoError(t, err)
|
|
cmdMocks.AssertNotCalled(t, "AuthReconcile")
|
|
})
|
|
|
|
t.Run("ReplaceResource should not call auth reconcile", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
cmdMocks.On("Replace", mock.Anything, mock.Anything).Return(nil)
|
|
|
|
_, err := k.ReplaceResource(t.Context(), role, cmdutil.DryRunNone, false)
|
|
require.NoError(t, err)
|
|
cmdMocks.AssertNotCalled(t, "AuthReconcile")
|
|
})
|
|
|
|
t.Run("ApplyResource should not call auth reconcile on server-side apply", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
cmdMocks.On("Apply", mock.Anything).Return(nil)
|
|
|
|
ssa := true
|
|
_, err := k.ApplyResource(t.Context(), role, cmdutil.DryRunNone, false, false, ssa, "")
|
|
require.NoError(t, err)
|
|
cmdMocks.AssertNotCalled(t, "AuthReconcile")
|
|
})
|
|
|
|
t.Run("ApplyResource should call auth reconcile on client-side apply", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
cmdMocks.On("Apply", mock.Anything).Return(nil)
|
|
cmdMocks.On("AuthReconcile", mock.Anything).Return(nil)
|
|
|
|
ssa := false
|
|
_, err := k.ApplyResource(t.Context(), role, cmdutil.DryRunNone, false, false, ssa, "")
|
|
require.NoError(t, err)
|
|
})
|
|
}
|
|
|
|
func TestOutputModeLog(t *testing.T) {
|
|
t.Parallel()
|
|
// Test normal flow operations with outputModeLog
|
|
|
|
t.Run("CreateResource with outputModeLog", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
cmdMocks.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.CreateResource(t.Context(), obj, cmdutil.DryRunNone, false)
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("ReplaceResource with outputModeLog", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
cmdMocks.On("Replace", mock.Anything, mock.Anything).Return(nil)
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.ReplaceResource(t.Context(), obj, cmdutil.DryRunNone, false)
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("ApplyResource with outputModeLog and client-side apply", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
cmdMocks.On("Apply", mock.Anything).Return(nil)
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.ApplyResource(t.Context(), obj, cmdutil.DryRunNone, false, false, false, "test-manager")
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("ApplyResource with outputModeLog and server-side apply", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
cmdMocks.On("Apply", mock.Anything).Return(nil)
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.ApplyResource(t.Context(), obj, cmdutil.DryRunNone, false, false, true, "test-manager")
|
|
require.NoError(t, err)
|
|
})
|
|
}
|
|
|
|
func TestOutputModeJSON(t *testing.T) {
|
|
t.Parallel()
|
|
// Test JSON output mode operations
|
|
|
|
t.Run("CreateResource with outputModeJSON should fail", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, _ := newTestKubectlResourceOperations(t)
|
|
k.outputMode = outputModeJSON
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.CreateResource(t.Context(), obj, cmdutil.DryRunServer, false)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "CreateResource is not supported with JSON output mode")
|
|
})
|
|
|
|
t.Run("ReplaceResource with outputModeJSON should fail", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, _ := newTestKubectlResourceOperations(t)
|
|
k.outputMode = outputModeJSON
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.ReplaceResource(t.Context(), obj, cmdutil.DryRunServer, false)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "ReplaceResource is not supported with JSON output mode")
|
|
})
|
|
|
|
t.Run("ApplyResource with outputModeJSON without Dry run", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, _ := newTestKubectlResourceOperations(t)
|
|
k.outputMode = outputModeJSON
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.ApplyResource(t.Context(), obj, cmdutil.DryRunNone, false, false, true, "test-manager")
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "invalid dry run strategy used with JSON output")
|
|
})
|
|
|
|
t.Run("ApplyResource with outputModeJSON requires DryRunServer", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, _ := newTestKubectlResourceOperations(t)
|
|
k.outputMode = outputModeJSON
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.ApplyResource(t.Context(), obj, cmdutil.DryRunClient, false, false, true, "test-manager")
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "invalid dry run strategy used with JSON output")
|
|
})
|
|
|
|
t.Run("ApplyResource with outputModeJSON requires server-side apply", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, _ := newTestKubectlResourceOperations(t)
|
|
k.outputMode = outputModeJSON
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.ApplyResource(t.Context(), obj, cmdutil.DryRunServer, false, false, false, "test-manager")
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "invalid Apply strategy used with JSON output")
|
|
})
|
|
|
|
t.Run("ApplyResource with outputModeJSON return object", func(t *testing.T) {
|
|
t.Parallel()
|
|
obj := testingutils.NewPod()
|
|
jsonObj, err := json.Marshal(obj)
|
|
require.NoError(t, err)
|
|
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
k.outputMode = outputModeJSON
|
|
cmdMocks.On("Apply", mock.Anything).Run(func(args mock.Arguments) {
|
|
applyOpts := args[0].(*apply.ApplyOptions)
|
|
_, err := applyOpts.Out.Write(jsonObj)
|
|
require.NoError(t, err)
|
|
}).Return(nil)
|
|
|
|
result, err := k.ApplyResource(t.Context(), obj, cmdutil.DryRunServer, false, false, true, "test-manager")
|
|
require.NoError(t, err)
|
|
assert.JSONEq(t, string(jsonObj), result)
|
|
})
|
|
|
|
t.Run("ApplyResource with outputModeJSON with object and stderr returns object", func(t *testing.T) {
|
|
t.Parallel()
|
|
obj := testingutils.NewPod()
|
|
jsonObj, err := json.Marshal(obj)
|
|
require.NoError(t, err)
|
|
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
k.outputMode = outputModeJSON
|
|
cmdMocks.On("Apply", mock.Anything).Run(func(args mock.Arguments) {
|
|
applyOpts := args[0].(*apply.ApplyOptions)
|
|
_, err := applyOpts.Out.Write(jsonObj)
|
|
require.NoError(t, err)
|
|
|
|
// add an stderr message that should not be returned in the result
|
|
_, err = applyOpts.ErrOut.Write([]byte("error message"))
|
|
require.NoError(t, err)
|
|
}).Return(nil)
|
|
|
|
result, err := k.ApplyResource(t.Context(), obj, cmdutil.DryRunServer, false, false, true, "test-manager")
|
|
require.NoError(t, err)
|
|
assert.JSONEq(t, string(jsonObj), result)
|
|
})
|
|
|
|
t.Run("ApplyResource with outputModeJSON without object with a stderr returns error", func(t *testing.T) {
|
|
t.Parallel()
|
|
obj := testingutils.NewPod()
|
|
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
k.outputMode = outputModeJSON
|
|
cmdMocks.On("Apply", mock.Anything).Run(func(args mock.Arguments) {
|
|
applyOpts := args[0].(*apply.ApplyOptions)
|
|
|
|
_, err := applyOpts.ErrOut.Write([]byte("error message"))
|
|
require.NoError(t, err)
|
|
}).Return(nil)
|
|
|
|
_, err := k.ApplyResource(t.Context(), obj, cmdutil.DryRunServer, false, false, true, "test-manager")
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "error message")
|
|
})
|
|
}
|
|
|
|
func TestApplyOptionsConfiguration(t *testing.T) {
|
|
t.Parallel()
|
|
// Test that newApplyOptions correctly configures all ApplyOptions fields
|
|
t.Run("general options are correctly set", func(t *testing.T) {
|
|
t.Parallel()
|
|
testCases := []struct {
|
|
name string
|
|
strategy cmdutil.DryRunStrategy
|
|
}{
|
|
{"DryRunNone", cmdutil.DryRunNone},
|
|
{"DryRunClient", cmdutil.DryRunClient},
|
|
{"DryRunServer", cmdutil.DryRunServer},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
|
|
var capturedOpts *apply.ApplyOptions
|
|
cmdMocks.On("Apply", mock.Anything).Run(func(args mock.Arguments) {
|
|
capturedOpts = args[0].(*apply.ApplyOptions)
|
|
}).Return(nil)
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.ApplyResource(t.Context(), obj, tc.strategy, false, false, false, "test-manager")
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, tc.strategy, capturedOpts.DryRunStrategy)
|
|
assert.Equal(t, "test-manager", capturedOpts.FieldManager)
|
|
assert.True(t, capturedOpts.Overwrite)
|
|
if tc.strategy == cmdutil.DryRunClient {
|
|
// workaround for https://github.com/kubernetes/kubernetes/issues/139538
|
|
// in kubectl v1.36
|
|
assert.False(t, capturedOpts.OpenAPIPatch)
|
|
} else {
|
|
assert.True(t, capturedOpts.OpenAPIPatch)
|
|
}
|
|
assert.False(t, capturedOpts.ServerSideApply)
|
|
assert.False(t, capturedOpts.ForceConflicts)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("serverSideApply=true sets ServerSideApply=true and ForceConflicts=true", func(t *testing.T) {
|
|
t.Parallel()
|
|
testCases := []struct {
|
|
name string
|
|
strategy cmdutil.DryRunStrategy
|
|
expectedError string
|
|
}{
|
|
{"DryRunNone", cmdutil.DryRunNone, ""},
|
|
{"DryRunClient", cmdutil.DryRunClient, "error validating options: --dry-run=client doesn't work with --server-side"},
|
|
{"DryRunServer", cmdutil.DryRunServer, ""},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
|
|
var capturedOpts *apply.ApplyOptions
|
|
if tc.expectedError == "" {
|
|
cmdMocks.On("Apply", mock.Anything).Run(func(args mock.Arguments) {
|
|
capturedOpts = args[0].(*apply.ApplyOptions)
|
|
}).Return(nil)
|
|
}
|
|
|
|
ssa := true
|
|
obj := testingutils.NewPod()
|
|
_, err := k.ApplyResource(t.Context(), obj, tc.strategy, false, false, ssa, "test-manager")
|
|
|
|
if tc.expectedError == "" {
|
|
require.NoError(t, err)
|
|
assert.True(t, capturedOpts.ServerSideApply)
|
|
assert.True(t, capturedOpts.ForceConflicts)
|
|
} else {
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), tc.expectedError)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("force=true sets DeleteOptions.ForceDeletion", func(t *testing.T) {
|
|
t.Parallel()
|
|
testCases := []struct {
|
|
name string
|
|
strategy cmdutil.DryRunStrategy
|
|
}{
|
|
{"DryRunNone", cmdutil.DryRunNone},
|
|
{"DryRunClient", cmdutil.DryRunClient},
|
|
{"DryRunServer", cmdutil.DryRunServer},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
|
|
var capturedOpts *apply.ApplyOptions
|
|
cmdMocks.On("Apply", mock.Anything).Run(func(args mock.Arguments) {
|
|
capturedOpts = args[0].(*apply.ApplyOptions)
|
|
}).Return(nil)
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.ApplyResource(t.Context(), obj, cmdutil.DryRunNone, true, false, false, "")
|
|
require.NoError(t, err)
|
|
|
|
assert.True(t, capturedOpts.DeleteOptions.ForceDeletion)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("outputModeJSON returns JSONPrinter", func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
k.outputMode = outputModeJSON
|
|
|
|
var capturedOpts *apply.ApplyOptions
|
|
cmdMocks.On("Apply", mock.Anything).Run(func(args mock.Arguments) {
|
|
capturedOpts = args[0].(*apply.ApplyOptions)
|
|
}).Return(nil)
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.ApplyResource(t.Context(), obj, cmdutil.DryRunServer, false, false, true, "test-manager")
|
|
require.NoError(t, err)
|
|
|
|
// Call ToPrinter and verify it returns a JSON printer
|
|
printer, err := capturedOpts.ToPrinter("configured")
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, printer)
|
|
|
|
// Verify it's a JSONPrinter by checking the type
|
|
_, isJSONPrinter := printer.(*printers.JSONPrinter)
|
|
assert.True(t, isJSONPrinter, "Expected printer to be of type *printers.JSONPrinter")
|
|
|
|
// Verify ShowManagedFields is set to true for JSON output
|
|
assert.True(t, capturedOpts.PrintFlags.JSONYamlPrintFlags.ShowManagedFields)
|
|
})
|
|
}
|
|
|
|
func TestCreateOptionsConfiguration(t *testing.T) {
|
|
t.Parallel()
|
|
// Test that newCreateOptions correctly configures all CreateOptions fields
|
|
|
|
t.Run("general options are correctly set", func(t *testing.T) {
|
|
t.Parallel()
|
|
testCases := []struct {
|
|
name string
|
|
strategy cmdutil.DryRunStrategy
|
|
}{
|
|
{"DryRunNone", cmdutil.DryRunNone},
|
|
{"DryRunClient", cmdutil.DryRunClient},
|
|
{"DryRunServer", cmdutil.DryRunServer},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
|
|
var capturedOpts *create.CreateOptions
|
|
cmdMocks.On("Create", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
|
|
capturedOpts = args[0].(*create.CreateOptions)
|
|
}).Return(nil)
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.CreateResource(t.Context(), obj, tc.strategy, false)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, tc.strategy, capturedOpts.DryRunStrategy)
|
|
assert.NotEmpty(t, capturedOpts.FilenameOptions.Filenames)
|
|
assert.NotNil(t, capturedOpts.PrintObj)
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestReplaceOptionsConfiguration(t *testing.T) {
|
|
t.Parallel()
|
|
// Test that newReplaceOptions correctly configures all ReplaceOptions fields
|
|
|
|
t.Run("general options are correctly set", func(t *testing.T) {
|
|
t.Parallel()
|
|
testCases := []struct {
|
|
name string
|
|
strategy cmdutil.DryRunStrategy
|
|
}{
|
|
{"DryRunNone", cmdutil.DryRunNone},
|
|
{"DryRunClient", cmdutil.DryRunClient},
|
|
{"DryRunServer", cmdutil.DryRunServer},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
|
|
var capturedOpts *replace.ReplaceOptions
|
|
cmdMocks.On("Replace", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
|
|
capturedOpts = args[0].(*replace.ReplaceOptions)
|
|
}).Return(nil)
|
|
|
|
obj := testingutils.NewPod()
|
|
obj.SetNamespace("test-namespace")
|
|
_, err := k.ReplaceResource(t.Context(), obj, tc.strategy, false)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, tc.strategy, capturedOpts.DryRunStrategy)
|
|
assert.False(t, capturedOpts.DeleteOptions.ForceDeletion)
|
|
assert.NotEmpty(t, capturedOpts.DeleteOptions.Filenames)
|
|
assert.Equal(t, "test-namespace", capturedOpts.Namespace)
|
|
assert.NotNil(t, capturedOpts.PrintObj)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("force=true sets DeleteOptions.ForceDeletion correctly", func(t *testing.T) {
|
|
t.Parallel()
|
|
testCases := []struct {
|
|
name string
|
|
strategy cmdutil.DryRunStrategy
|
|
expected bool
|
|
}{
|
|
{"DryRunNone", cmdutil.DryRunNone, true},
|
|
{"DryRunClient", cmdutil.DryRunClient, false},
|
|
{"DryRunServer", cmdutil.DryRunServer, false},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
k, cmdMocks := newTestKubectlResourceOperations(t)
|
|
|
|
var capturedOpts *replace.ReplaceOptions
|
|
cmdMocks.On("Replace", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
|
|
capturedOpts = args[0].(*replace.ReplaceOptions)
|
|
}).Return(nil)
|
|
|
|
obj := testingutils.NewPod()
|
|
_, err := k.ReplaceResource(t.Context(), obj, tc.strategy, true)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, tc.expected, capturedOpts.DeleteOptions.ForceDeletion)
|
|
})
|
|
}
|
|
})
|
|
}
|