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  }