2019-07-15 18:19:38 +00:00
/ *
Copyright 2019 the Velero contributors .
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 .
* /
package restore
import (
k8s 1.18 import (#2651)
* k8s 1.18 import wip
backup, cmd, controller, generated, restic, restore, serverstatusrequest, test and util
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* go mod tidy
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* add changelog file
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* go fmt
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* update code-generator and controller-gen in CI
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* checkout proper code-generator version, regen
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* fix remaining calls
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* regenerate CRDs with ./hack/update-generated-crd-code.sh
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* use existing context in restic and server
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* fix test cases by resetting resource version
also use main library go context, not golang.org/x/net/context, in pkg/restore/restore.go
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* clarify changelog message
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* use github.com/kubernetes-csi/external-snapshotter/v2@v2.2.0-rc1
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* run 'go mod tidy' to remove old external-snapshotter version
Signed-off-by: Andrew Lavery <laverya@umich.edu>
2020-07-16 16:21:37 +00:00
"context"
2019-07-15 18:19:38 +00:00
"testing"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
corev1api "k8s.io/api/core/v1"
storagev1api "k8s.io/api/storage/v1"
k8s 1.18 import (#2651)
* k8s 1.18 import wip
backup, cmd, controller, generated, restic, restore, serverstatusrequest, test and util
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* go mod tidy
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* add changelog file
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* go fmt
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* update code-generator and controller-gen in CI
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* checkout proper code-generator version, regen
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* fix remaining calls
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* regenerate CRDs with ./hack/update-generated-crd-code.sh
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* use existing context in restic and server
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* fix test cases by resetting resource version
also use main library go context, not golang.org/x/net/context, in pkg/restore/restore.go
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* clarify changelog message
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* use github.com/kubernetes-csi/external-snapshotter/v2@v2.2.0-rc1
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* run 'go mod tidy' to remove old external-snapshotter version
Signed-off-by: Andrew Lavery <laverya@umich.edu>
2020-07-16 16:21:37 +00:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2019-07-15 18:19:38 +00:00
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/fake"
2019-09-30 21:26:56 +00:00
"github.com/vmware-tanzu/velero/pkg/builder"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
2019-07-15 18:19:38 +00:00
)
// TestChangeStorageClassActionExecute runs the ChangeStorageClassAction's Execute
// method and validates that the item's storage class is modified (or not) as expected.
// Validation is done by comparing the result of the Execute method to the test case's
// desired result.
func TestChangeStorageClassActionExecute ( t * testing . T ) {
tests := [ ] struct {
2021-12-16 06:50:56 +00:00
name string
pvOrPvcOrSTS interface { }
configMap * corev1api . ConfigMap
storageClass * storagev1api . StorageClass
storageClassSlice [ ] * storagev1api . StorageClass
want interface { }
wantErr error
2019-07-15 18:19:38 +00:00
} {
{
2021-12-16 06:50:56 +00:00
name : "a valid mapping for a persistent volume is applied correctly" ,
pvOrPvcOrSTS : builder . ForPersistentVolume ( "pv-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
2019-07-31 14:46:48 +00:00
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-1" , "storageclass-2" ) .
Result ( ) ,
storageClass : builder . ForStorageClass ( "storageclass-2" ) . Result ( ) ,
want : builder . ForPersistentVolume ( "pv-1" ) . StorageClass ( "storageclass-2" ) . Result ( ) ,
2019-07-15 18:19:38 +00:00
} ,
{
2021-12-16 06:50:56 +00:00
name : "a valid mapping for a persistent volume claim is applied correctly" ,
pvOrPvcOrSTS : builder . ForPersistentVolumeClaim ( "velero" , "pvc-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
2019-07-31 14:46:48 +00:00
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-1" , "storageclass-2" ) .
Result ( ) ,
storageClass : builder . ForStorageClass ( "storageclass-2" ) . Result ( ) ,
want : builder . ForPersistentVolumeClaim ( "velero" , "pvc-1" ) . StorageClass ( "storageclass-2" ) . Result ( ) ,
2019-07-15 18:19:38 +00:00
} ,
{
2021-12-16 06:50:56 +00:00
name : "when no config map exists for the plugin, the item is returned as-is" ,
pvOrPvcOrSTS : builder . ForPersistentVolume ( "pv-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
2019-07-31 14:46:48 +00:00
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/some-other-plugin" , "RestoreItemAction" ) ) .
Data ( "storageclass-1" , "storageclass-2" ) .
Result ( ) ,
want : builder . ForPersistentVolume ( "pv-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
2019-07-15 18:19:38 +00:00
} ,
{
2021-12-16 06:50:56 +00:00
name : "when no storage class mappings exist in the plugin config map, the item is returned as-is" ,
pvOrPvcOrSTS : builder . ForPersistentVolume ( "pv-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
2019-07-31 14:46:48 +00:00
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Result ( ) ,
want : builder . ForPersistentVolume ( "pv-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
2019-07-15 18:19:38 +00:00
} ,
{
2021-12-16 06:50:56 +00:00
name : "when persistent volume has no storage class, the item is returned as-is" ,
pvOrPvcOrSTS : builder . ForPersistentVolume ( "pv-1" ) . Result ( ) ,
2019-07-31 14:46:48 +00:00
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-1" , "storageclass-2" ) .
Result ( ) ,
want : builder . ForPersistentVolume ( "pv-1" ) . Result ( ) ,
2019-07-15 18:19:38 +00:00
} ,
{
2021-12-16 06:50:56 +00:00
name : "when persistent volume claim has no storage class, the item is returned as-is" ,
pvOrPvcOrSTS : builder . ForPersistentVolumeClaim ( "velero" , "pvc-1" ) . Result ( ) ,
2019-07-31 14:46:48 +00:00
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-1" , "storageclass-2" ) .
Result ( ) ,
want : builder . ForPersistentVolumeClaim ( "velero" , "pvc-1" ) . Result ( ) ,
2019-07-15 18:19:38 +00:00
} ,
{
2021-12-16 06:50:56 +00:00
name : "when persistent volume's storage class has no mapping in the config map, the item is returned as-is" ,
pvOrPvcOrSTS : builder . ForPersistentVolume ( "pv-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
2019-07-31 14:46:48 +00:00
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-3" , "storageclass-4" ) .
Result ( ) ,
want : builder . ForPersistentVolume ( "pv-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
2019-07-15 18:19:38 +00:00
} ,
{
2021-12-16 06:50:56 +00:00
name : "when persistent volume claim's storage class has no mapping in the config map, the item is returned as-is" ,
pvOrPvcOrSTS : builder . ForPersistentVolumeClaim ( "velero" , "pvc-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
2019-07-31 14:46:48 +00:00
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-3" , "storageclass-4" ) .
Result ( ) ,
want : builder . ForPersistentVolumeClaim ( "velero" , "pvc-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
2019-07-15 18:19:38 +00:00
} ,
{
2021-12-16 06:50:56 +00:00
name : "when persistent volume's storage class is mapped to a nonexistent storage class, an error is returned" ,
pvOrPvcOrSTS : builder . ForPersistentVolume ( "pv-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
2019-07-31 14:46:48 +00:00
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-1" , "nonexistent-storage-class" ) .
Result ( ) ,
2019-07-15 18:19:38 +00:00
wantErr : errors . New ( "error getting storage class nonexistent-storage-class from API: storageclasses.storage.k8s.io \"nonexistent-storage-class\" not found" ) ,
} ,
{
2021-12-16 06:50:56 +00:00
name : "when persistent volume claim's storage class is mapped to a nonexistent storage class, an error is returned" ,
pvOrPvcOrSTS : builder . ForPersistentVolumeClaim ( "velero" , "pvc-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-1" , "nonexistent-storage-class" ) .
Result ( ) ,
wantErr : errors . New ( "error getting storage class nonexistent-storage-class from API: storageclasses.storage.k8s.io \"nonexistent-storage-class\" not found" ) ,
} ,
{
name : "when statefulset's VolumeClaimTemplates has only one pvc, a valid mapping for a statefulset is applied correctly" ,
pvOrPvcOrSTS : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-1" , "storageclass-2" ) .
Result ( ) ,
storageClass : builder . ForStorageClass ( "storageclass-2" ) . Result ( ) ,
want : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-2" ) . Result ( ) ,
} ,
{
name : "when statefulset's VolumeClaimTemplates has more than one same pvc's storageClassName, a valid mapping for a statefulset is applied correctly" ,
pvOrPvcOrSTS : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-1" , "storageclass-1" ) . Result ( ) ,
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-1" , "storageclass-2" , "storageclass-3" , "storageclass-4" ) .
Result ( ) ,
storageClass : builder . ForStorageClass ( "storageclass-2" ) . Result ( ) ,
want : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-2" , "storageclass-2" ) . Result ( ) ,
} ,
{
name : "when statefulset's VolumeClaimTemplates has more than one different pvc's storageClassName, a valid mapping for a statefulset is applied correctly" ,
pvOrPvcOrSTS : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-1" , "storageclass-2" , "storageclass-3" ) . Result ( ) ,
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-1" , "storageclass-a" , "storageclass-2" , "storageclass-b" , "storageclass-3" , "storageclass-c" ) .
Result ( ) ,
storageClassSlice : builder . ForStorageClassSlice ( "storageclass-a" , "storageclass-b" , "storageclass-c" ) . SliceResult ( ) ,
want : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-a" , "storageclass-b" , "storageclass-c" ) . Result ( ) ,
} ,
{
name : "when no config map exists for the plugin, the statefulset item is returned as-is" ,
pvOrPvcOrSTS : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/some-other-plugin" , "RestoreItemAction" ) ) .
Data ( "storageclass-1" , "storageclass-2" ) .
Result ( ) ,
want : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
} ,
{
name : "when no storage class mappings exist in the plugin config map, the statefulset item is returned as-is" ,
pvOrPvcOrSTS : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Result ( ) ,
want : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
} ,
{
name : "when persistent volume claim has no storage class, the statefulset item is returned as-is" ,
pvOrPvcOrSTS : builder . ForStatefulSet ( "velero" , "sts-1" ) . Result ( ) ,
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Result ( ) ,
want : builder . ForStatefulSet ( "velero" , "sts-1" ) . Result ( ) ,
} ,
{
name : "when statefulset's storage class has no mapping in the config map, the item is returned as-is" ,
pvOrPvcOrSTS : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-3" , "storageclass-4" ) .
Result ( ) ,
want : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
} ,
{
name : "when statefulset's storage class is mapped to a nonexistent storage class, an error is returned" ,
pvOrPvcOrSTS : builder . ForStatefulSet ( "velero" , "sts-1" ) . StorageClass ( "storageclass-1" ) . Result ( ) ,
2019-07-31 14:46:48 +00:00
configMap : builder . ForConfigMap ( "velero" , "change-storage-classs" ) .
ObjectMeta ( builder . WithLabels ( "velero.io/plugin-config" , "true" , "velero.io/change-storage-class" , "RestoreItemAction" ) ) .
Data ( "storageclass-1" , "nonexistent-storage-class" ) .
Result ( ) ,
2019-07-15 18:19:38 +00:00
wantErr : errors . New ( "error getting storage class nonexistent-storage-class from API: storageclasses.storage.k8s.io \"nonexistent-storage-class\" not found" ) ,
} ,
}
for _ , tc := range tests {
t . Run ( tc . name , func ( t * testing . T ) {
clientset := fake . NewSimpleClientset ( )
a := NewChangeStorageClassAction (
logrus . StandardLogger ( ) ,
clientset . CoreV1 ( ) . ConfigMaps ( "velero" ) ,
clientset . StorageV1 ( ) . StorageClasses ( ) ,
)
// set up test data
if tc . configMap != nil {
k8s 1.18 import (#2651)
* k8s 1.18 import wip
backup, cmd, controller, generated, restic, restore, serverstatusrequest, test and util
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* go mod tidy
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* add changelog file
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* go fmt
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* update code-generator and controller-gen in CI
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* checkout proper code-generator version, regen
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* fix remaining calls
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* regenerate CRDs with ./hack/update-generated-crd-code.sh
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* use existing context in restic and server
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* fix test cases by resetting resource version
also use main library go context, not golang.org/x/net/context, in pkg/restore/restore.go
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* clarify changelog message
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* use github.com/kubernetes-csi/external-snapshotter/v2@v2.2.0-rc1
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* run 'go mod tidy' to remove old external-snapshotter version
Signed-off-by: Andrew Lavery <laverya@umich.edu>
2020-07-16 16:21:37 +00:00
_ , err := clientset . CoreV1 ( ) . ConfigMaps ( tc . configMap . Namespace ) . Create ( context . TODO ( ) , tc . configMap , metav1 . CreateOptions { } )
2019-07-15 18:19:38 +00:00
require . NoError ( t , err )
}
if tc . storageClass != nil {
k8s 1.18 import (#2651)
* k8s 1.18 import wip
backup, cmd, controller, generated, restic, restore, serverstatusrequest, test and util
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* go mod tidy
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* add changelog file
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* go fmt
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* update code-generator and controller-gen in CI
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* checkout proper code-generator version, regen
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* fix remaining calls
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* regenerate CRDs with ./hack/update-generated-crd-code.sh
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* use existing context in restic and server
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* fix test cases by resetting resource version
also use main library go context, not golang.org/x/net/context, in pkg/restore/restore.go
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* clarify changelog message
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* use github.com/kubernetes-csi/external-snapshotter/v2@v2.2.0-rc1
Signed-off-by: Andrew Lavery <laverya@umich.edu>
* run 'go mod tidy' to remove old external-snapshotter version
Signed-off-by: Andrew Lavery <laverya@umich.edu>
2020-07-16 16:21:37 +00:00
_ , err := clientset . StorageV1 ( ) . StorageClasses ( ) . Create ( context . TODO ( ) , tc . storageClass , metav1 . CreateOptions { } )
2019-07-15 18:19:38 +00:00
require . NoError ( t , err )
}
2021-12-16 06:50:56 +00:00
if tc . storageClassSlice != nil {
for _ , storageClass := range tc . storageClassSlice {
_ , err := clientset . StorageV1 ( ) . StorageClasses ( ) . Create ( context . TODO ( ) , storageClass , metav1 . CreateOptions { } )
require . NoError ( t , err )
}
}
unstructuredMap , err := runtime . DefaultUnstructuredConverter . ToUnstructured ( tc . pvOrPvcOrSTS )
2019-07-15 18:19:38 +00:00
require . NoError ( t , err )
input := & velero . RestoreItemActionExecuteInput {
Item : & unstructured . Unstructured {
Object : unstructuredMap ,
} ,
}
// execute method under test
res , err := a . Execute ( input )
// validate for both error and non-error cases
switch {
case tc . wantErr != nil :
assert . EqualError ( t , err , tc . wantErr . Error ( ) )
default :
assert . NoError ( t , err )
wantUnstructured , err := runtime . DefaultUnstructuredConverter . ToUnstructured ( tc . want )
require . NoError ( t , err )
assert . Equal ( t , & unstructured . Unstructured { Object : wantUnstructured } , res . UpdatedItem )
}
} )
}
}