github.com/crossplane/upjet@v1.3.0/pkg/controller/api_test.go (about) 1 // SPDX-FileCopyrightText: 2023 The Crossplane Authors <https://crossplane.io> 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package controller 6 7 import ( 8 "context" 9 "testing" 10 11 xpresource "github.com/crossplane/crossplane-runtime/pkg/resource" 12 xpfake "github.com/crossplane/crossplane-runtime/pkg/resource/fake" 13 "github.com/crossplane/crossplane-runtime/pkg/test" 14 "github.com/google/go-cmp/cmp" 15 "github.com/pkg/errors" 16 "sigs.k8s.io/controller-runtime/pkg/client" 17 ctrl "sigs.k8s.io/controller-runtime/pkg/manager" 18 19 "github.com/crossplane/upjet/pkg/resource" 20 "github.com/crossplane/upjet/pkg/resource/fake" 21 tjerrors "github.com/crossplane/upjet/pkg/terraform/errors" 22 ) 23 24 func TestAPICallbacksCreate(t *testing.T) { 25 type args struct { 26 mgr ctrl.Manager 27 mg xpresource.ManagedKind 28 err error 29 } 30 type want struct { 31 err error 32 } 33 cases := map[string]struct { 34 reason string 35 args 36 want 37 }{ 38 "CreateOperationFailed": { 39 reason: "It should update the condition with error if async apply failed", 40 args: args{ 41 mg: xpresource.ManagedKind(xpfake.GVK(&fake.Terraformed{})), 42 mgr: &xpfake.Manager{ 43 Client: &test.MockClient{ 44 MockGet: test.NewMockGetFn(nil), 45 MockStatusUpdate: func(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { 46 got := obj.(resource.Terraformed).GetCondition(resource.TypeLastAsyncOperation) 47 if diff := cmp.Diff(resource.LastAsyncOperationCondition(tjerrors.NewApplyFailed(nil)), got); diff != "" { 48 t.Errorf("\nCreate(...): -want error, +got error:\n%s", diff) 49 } 50 return nil 51 }, 52 }, 53 Scheme: xpfake.SchemeWith(&fake.Terraformed{}), 54 }, 55 err: tjerrors.NewApplyFailed(nil), 56 }, 57 }, 58 "CreateOperationSucceeded": { 59 reason: "It should update the condition with success if the apply operation does not report error", 60 args: args{ 61 mg: xpresource.ManagedKind(xpfake.GVK(&fake.Terraformed{})), 62 mgr: &xpfake.Manager{ 63 Client: &test.MockClient{ 64 MockGet: test.NewMockGetFn(nil), 65 MockStatusUpdate: func(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { 66 got := obj.(resource.Terraformed).GetCondition(resource.TypeLastAsyncOperation) 67 if diff := cmp.Diff(resource.LastAsyncOperationCondition(nil), got); diff != "" { 68 t.Errorf("\nCreate(...): -want error, +got error:\n%s", diff) 69 } 70 return nil 71 }, 72 }, 73 Scheme: xpfake.SchemeWith(&fake.Terraformed{}), 74 }, 75 }, 76 }, 77 "CannotGet": { 78 reason: "It should return error if it cannot get the resource to update", 79 args: args{ 80 mg: xpresource.ManagedKind(xpfake.GVK(&fake.Terraformed{})), 81 mgr: &xpfake.Manager{ 82 Client: &test.MockClient{ 83 MockGet: func(_ context.Context, _ client.ObjectKey, _ client.Object) error { 84 return errBoom 85 }, 86 }, 87 Scheme: xpfake.SchemeWith(&fake.Terraformed{}), 88 }, 89 }, 90 want: want{ 91 err: errors.Wrapf(errBoom, errGetFmt, "", ", Kind=/name", "create"), 92 }, 93 }, 94 } 95 for name, tc := range cases { 96 t.Run(name, func(t *testing.T) { 97 e := NewAPICallbacks(tc.args.mgr, tc.args.mg) 98 err := e.Create("name")(tc.args.err, context.TODO()) 99 if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" { 100 t.Errorf("\n%s\nCreate(...): -want error, +got error:\n%s", tc.reason, diff) 101 } 102 }) 103 } 104 } 105 106 func TestAPICallbacksUpdate(t *testing.T) { 107 type args struct { 108 mgr ctrl.Manager 109 mg xpresource.ManagedKind 110 err error 111 } 112 type want struct { 113 err error 114 } 115 cases := map[string]struct { 116 reason string 117 args 118 want 119 }{ 120 "UpdateOperationFailed": { 121 reason: "It should update the condition with error if async apply failed", 122 args: args{ 123 mg: xpresource.ManagedKind(xpfake.GVK(&fake.Terraformed{})), 124 mgr: &xpfake.Manager{ 125 Client: &test.MockClient{ 126 MockGet: test.NewMockGetFn(nil), 127 MockStatusUpdate: func(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { 128 got := obj.(resource.Terraformed).GetCondition(resource.TypeLastAsyncOperation) 129 if diff := cmp.Diff(resource.LastAsyncOperationCondition(tjerrors.NewApplyFailed(nil)), got); diff != "" { 130 t.Errorf("\nUpdate(...): -want error, +got error:\n%s", diff) 131 } 132 return nil 133 }, 134 }, 135 Scheme: xpfake.SchemeWith(&fake.Terraformed{}), 136 }, 137 err: tjerrors.NewApplyFailed(nil), 138 }, 139 }, 140 "ApplyOperationSucceeded": { 141 reason: "It should update the condition with success if the apply operation does not report error", 142 args: args{ 143 mg: xpresource.ManagedKind(xpfake.GVK(&fake.Terraformed{})), 144 mgr: &xpfake.Manager{ 145 Client: &test.MockClient{ 146 MockGet: test.NewMockGetFn(nil), 147 MockStatusUpdate: func(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { 148 got := obj.(resource.Terraformed).GetCondition(resource.TypeLastAsyncOperation) 149 if diff := cmp.Diff(resource.LastAsyncOperationCondition(nil), got); diff != "" { 150 t.Errorf("\nUpdate(...): -want error, +got error:\n%s", diff) 151 } 152 return nil 153 }, 154 }, 155 Scheme: xpfake.SchemeWith(&fake.Terraformed{}), 156 }, 157 }, 158 }, 159 "CannotGet": { 160 reason: "It should return error if it cannot get the resource to update", 161 args: args{ 162 mg: xpresource.ManagedKind(xpfake.GVK(&fake.Terraformed{})), 163 mgr: &xpfake.Manager{ 164 Client: &test.MockClient{ 165 MockGet: func(_ context.Context, _ client.ObjectKey, _ client.Object) error { 166 return errBoom 167 }, 168 }, 169 Scheme: xpfake.SchemeWith(&fake.Terraformed{}), 170 }, 171 }, 172 want: want{ 173 err: errors.Wrapf(errBoom, errGetFmt, "", ", Kind=/name", "update"), 174 }, 175 }, 176 } 177 for name, tc := range cases { 178 t.Run(name, func(t *testing.T) { 179 e := NewAPICallbacks(tc.args.mgr, tc.args.mg) 180 err := e.Update("name")(tc.args.err, context.TODO()) 181 if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" { 182 t.Errorf("\n%s\nUpdate(...): -want error, +got error:\n%s", tc.reason, diff) 183 } 184 }) 185 } 186 } 187 188 func TestAPICallbacks_Destroy(t *testing.T) { 189 type args struct { 190 mgr ctrl.Manager 191 mg xpresource.ManagedKind 192 err error 193 } 194 type want struct { 195 err error 196 } 197 cases := map[string]struct { 198 reason string 199 args 200 want 201 }{ 202 "DestroyOperationFailed": { 203 reason: "It should update the condition with error if async destroy failed", 204 args: args{ 205 mg: xpresource.ManagedKind(xpfake.GVK(&fake.Terraformed{})), 206 mgr: &xpfake.Manager{ 207 Client: &test.MockClient{ 208 MockGet: test.NewMockGetFn(nil), 209 MockStatusUpdate: func(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { 210 got := obj.(resource.Terraformed).GetCondition(resource.TypeLastAsyncOperation) 211 if diff := cmp.Diff(resource.LastAsyncOperationCondition(tjerrors.NewDestroyFailed(nil)), got); diff != "" { 212 t.Errorf("\nApply(...): -want error, +got error:\n%s", diff) 213 } 214 return nil 215 }, 216 }, 217 Scheme: xpfake.SchemeWith(&fake.Terraformed{}), 218 }, 219 err: tjerrors.NewDestroyFailed(nil), 220 }, 221 }, 222 "DestroyOperationSucceeded": { 223 reason: "It should update the condition with success if the destroy operation does not report error", 224 args: args{ 225 mg: xpresource.ManagedKind(xpfake.GVK(&fake.Terraformed{})), 226 mgr: &xpfake.Manager{ 227 Client: &test.MockClient{ 228 MockGet: test.NewMockGetFn(nil), 229 MockStatusUpdate: func(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { 230 got := obj.(resource.Terraformed).GetCondition(resource.TypeLastAsyncOperation) 231 if diff := cmp.Diff(resource.LastAsyncOperationCondition(nil), got); diff != "" { 232 t.Errorf("\nApply(...): -want error, +got error:\n%s", diff) 233 } 234 return nil 235 }, 236 }, 237 Scheme: xpfake.SchemeWith(&fake.Terraformed{}), 238 }, 239 }, 240 }, 241 "CannotGet": { 242 reason: "It should return error if it cannot get the resource to update", 243 args: args{ 244 mg: xpresource.ManagedKind(xpfake.GVK(&fake.Terraformed{})), 245 mgr: &xpfake.Manager{ 246 Client: &test.MockClient{ 247 MockGet: func(_ context.Context, _ client.ObjectKey, _ client.Object) error { 248 return errBoom 249 }, 250 }, 251 Scheme: xpfake.SchemeWith(&fake.Terraformed{}), 252 }, 253 }, 254 want: want{ 255 err: errors.Wrapf(errBoom, errGetFmt, "", ", Kind=/name", "destroy"), 256 }, 257 }, 258 } 259 for name, tc := range cases { 260 t.Run(name, func(t *testing.T) { 261 e := NewAPICallbacks(tc.args.mgr, tc.args.mg) 262 err := e.Destroy("name")(tc.args.err, context.TODO()) 263 if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" { 264 t.Errorf("\n%s\nDestroy(...): -want error, +got error:\n%s", tc.reason, diff) 265 } 266 }) 267 } 268 }