github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/lib/controller-runtime/client/ssa_test.go (about) 1 package client 2 3 import ( 4 "context" 5 "strings" 6 "testing" 7 8 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 9 10 "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/testobj" 11 "github.com/stretchr/testify/require" 12 corev1 "k8s.io/api/core/v1" 13 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 14 "k8s.io/apimachinery/pkg/runtime" 15 "k8s.io/apimachinery/pkg/runtime/schema" 16 ) 17 18 func TestSetDefaultGroupVersionKind(t *testing.T) { 19 tests := []struct { 20 name string 21 schemebuilder runtime.SchemeBuilder 22 obj Object 23 want schema.GroupVersionKind 24 }{ 25 { 26 name: "DefaultGVK", 27 schemebuilder: corev1.SchemeBuilder, 28 obj: &corev1.ServiceAccount{}, 29 want: schema.GroupVersionKind{ 30 Group: "", 31 Version: "v1", 32 Kind: "ServiceAccount", 33 }, 34 }, 35 } 36 for _, tt := range tests { 37 t.Run(tt.name, func(t *testing.T) { 38 s := runtime.NewScheme() 39 err := tt.schemebuilder.AddToScheme(s) 40 require.NoError(t, err) 41 42 SetDefaultGroupVersionKind(tt.obj, s) 43 require.EqualValues(t, tt.want, tt.obj.GetObjectKind().GroupVersionKind()) 44 }) 45 } 46 } 47 48 // fake client doesn't support Server Side Apply 49 func applyError(err error) bool { 50 if err == nil { 51 return false 52 } 53 return strings.Contains(err.Error(), "/issues/115598") 54 } 55 56 func TestServerSideApply(t *testing.T) { 57 tests := []struct { 58 name string 59 obj Object 60 schemebuilder *runtime.SchemeBuilder 61 changeFunc interface{} 62 want Object 63 }{ 64 { 65 name: "ServerSideMetadataApply", 66 obj: &corev1.Pod{ 67 ObjectMeta: metav1.ObjectMeta{ 68 Name: "testpod", 69 Namespace: "testns", 70 Labels: map[string]string{ 71 "testlabel": "oldvalue", 72 }, 73 }, 74 }, 75 schemebuilder: &corev1.SchemeBuilder, 76 changeFunc: func(p *corev1.Pod) error { 77 p.Labels["testlabel"] = "newvalue" 78 return nil 79 }, 80 want: &corev1.Pod{ 81 TypeMeta: metav1.TypeMeta{ 82 Kind: "Pod", 83 APIVersion: "v1", 84 }, 85 ObjectMeta: metav1.ObjectMeta{ 86 Name: "testpod", 87 Namespace: "testns", 88 Labels: map[string]string{ 89 "testlabel": "newvalue", 90 }, 91 }, 92 }, 93 }, 94 { 95 name: "ServerSideStatusApply", 96 obj: &corev1.Pod{ 97 ObjectMeta: metav1.ObjectMeta{ 98 Name: "testpod", 99 Namespace: "testns", 100 }, 101 Status: corev1.PodStatus{Message: "new"}, 102 }, 103 schemebuilder: &corev1.SchemeBuilder, 104 changeFunc: func(p *corev1.Pod) error { 105 p.Status.Message = "new" 106 return nil 107 }, 108 want: &corev1.Pod{ 109 TypeMeta: metav1.TypeMeta{ 110 Kind: "Pod", 111 APIVersion: "v1", 112 }, 113 ObjectMeta: metav1.ObjectMeta{ 114 Name: "testpod", 115 Namespace: "testns", 116 }, 117 Status: corev1.PodStatus{Message: "new"}, 118 }, 119 }, 120 { 121 name: "ServerSideUnstructuredApply", 122 obj: &unstructured.Unstructured{ 123 Object: map[string]interface{}{ 124 "kind": "Pod", 125 "apiVersion": "v1", 126 "metadata": map[string]interface{}{ 127 "name": "testpod", 128 "namespace": "testns", 129 }, 130 "status": map[string]interface{}{ 131 "message": "old", 132 }, 133 }, 134 }, 135 schemebuilder: &corev1.SchemeBuilder, 136 changeFunc: func(u *unstructured.Unstructured) error { 137 return unstructured.SetNestedField(u.Object, "new", "status", "message") 138 }, 139 want: &corev1.Pod{ 140 TypeMeta: metav1.TypeMeta{ 141 Kind: "Pod", 142 APIVersion: "v1", 143 }, 144 ObjectMeta: metav1.ObjectMeta{ 145 Name: "testpod", 146 Namespace: "testns", 147 }, 148 Status: corev1.PodStatus{Message: "new"}, 149 }, 150 }, 151 } 152 for _, tt := range tests { 153 t.Run(tt.name, func(t *testing.T) { 154 s := runtime.NewScheme() 155 require.NoError(t, tt.schemebuilder.AddToScheme(s)) 156 157 applier := NewFakeApplier(s, "testowner", tt.obj) 158 err := applier.Apply(context.TODO(), tt.obj, tt.changeFunc)() 159 if applyError(err) { 160 return 161 } 162 require.NoError(t, err) 163 164 newObj := corev1.Pod{} 165 require.NoError(t, applier.client.Get(context.TODO(), testobj.NamespacedName(tt.obj), &newObj)) 166 167 newObj.ResourceVersion = "" 168 require.EqualValues(t, tt.want, &newObj) 169 }) 170 } 171 }