Skip to content

Commit e77a223

Browse files
committed
Inject patch failures with interceptors
1 parent d933fb9 commit e77a223

File tree

1 file changed

+58
-25
lines changed

1 file changed

+58
-25
lines changed

internal/generated/controller/flexcluster/handler_v20250312_test.go

Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"k8s.io/apimachinery/pkg/runtime"
3333
client "sigs.k8s.io/controller-runtime/pkg/client"
3434
"sigs.k8s.io/controller-runtime/pkg/client/fake"
35+
"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
3536
reconcile "sigs.k8s.io/controller-runtime/pkg/reconcile"
3637

3738
crapi "github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/crapi"
@@ -61,6 +62,7 @@ func TestHandleInitial(t *testing.T) {
6162
flexCluster *akov2generated.FlexCluster
6263
kubeObjects []client.Object
6364
atlasCreateFlexClusterFunc func() (*v20250312sdk.FlexClusterDescription20241113, *http.Response, error)
65+
interceptorFuncs *interceptor.Funcs
6466
want ctrlstate.Result
6567
wantErr string
6668
}{
@@ -123,9 +125,26 @@ func TestHandleInitial(t *testing.T) {
123125
want: ctrlstate.Result{NextState: state.StateInitial},
124126
wantErr: "failed to create flex cluster",
125127
},
128+
{
129+
title: "patch status fails",
130+
flexCluster: defaultTestFlexCluster(testClusterName, testNamespace),
131+
kubeObjects: []client.Object{
132+
defaultTestGroup(testGroupName, testNamespace, nil),
133+
},
134+
atlasCreateFlexClusterFunc: func() (*v20250312sdk.FlexClusterDescription20241113, *http.Response, error) {
135+
return &v20250312sdk.FlexClusterDescription20241113{Id: pointer.MakePtr(testClusterName)}, nil, nil
136+
},
137+
interceptorFuncs: &interceptor.Funcs{
138+
SubResourcePatch: func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
139+
return fmt.Errorf("simulated status patch failure")
140+
},
141+
},
142+
want: ctrlstate.Result{NextState: state.StateInitial},
143+
wantErr: "failed to patch flex cluster status",
144+
},
126145
} {
127146
t.Run(tc.title, func(t *testing.T) {
128-
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, false)
147+
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, tc.interceptorFuncs)
129148

130149
flexAPI := mockadmin.NewFlexClustersApi(t)
131150
if tc.atlasCreateFlexClusterFunc != nil {
@@ -215,7 +234,7 @@ func TestHandleImportRequested(t *testing.T) {
215234
},
216235
} {
217236
t.Run(tc.title, func(t *testing.T) {
218-
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, false)
237+
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, nil)
219238

220239
flexAPI := mockadmin.NewFlexClustersApi(t)
221240
if tc.atlasGetFlexClusterFunc != nil {
@@ -284,7 +303,7 @@ func TestHandleCreating(t *testing.T) {
284303
},
285304
} {
286305
t.Run(tc.title, func(t *testing.T) {
287-
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, false)
306+
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, nil)
288307

289308
flexAPI := mockadmin.NewFlexClustersApi(t)
290309
if tc.atlasGetFlexClusterFunc != nil {
@@ -347,7 +366,7 @@ func TestHandleUpdating(t *testing.T) {
347366
},
348367
} {
349368
t.Run(tc.title, func(t *testing.T) {
350-
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, false)
369+
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, nil)
351370

352371
flexAPI := mockadmin.NewFlexClustersApi(t)
353372
if tc.atlasGetFlexClusterFunc != nil {
@@ -377,19 +396,19 @@ func TestHandleCreated(t *testing.T) {
377396
flexCluster *akov2generated.FlexCluster
378397
kubeObjects []client.Object
379398
atlasUpdateFlexClusterFunc func() (*v20250312sdk.FlexClusterDescription20241113, *http.Response, error)
380-
skipStatusSubresource bool
399+
interceptorFuncs *interceptor.Funcs
381400
want ctrlstate.Result
382401
wantErr string
383402
}{
384403
{
385404
title: "no update needed",
386-
flexCluster: withObservedGeneration(
405+
flexCluster: withStateTracker(withObservedGeneration(
387406
withGeneration(
388407
setGroupRef(defaultTestFlexCluster(testClusterName, testNamespace), testGroupName),
389408
1,
390409
),
391410
1,
392-
),
411+
)),
393412
kubeObjects: []client.Object{
394413
defaultTestGroup(testGroupName, testNamespace, pointer.MakePtr(testGroupID)),
395414
},
@@ -510,13 +529,17 @@ func TestHandleCreated(t *testing.T) {
510529
StateName: pointer.MakePtr("IDLE"),
511530
}, nil, nil
512531
},
513-
skipStatusSubresource: true,
514-
want: errorResult(state.StateCreated),
515-
wantErr: "failed to patch cluster status",
532+
interceptorFuncs: &interceptor.Funcs{
533+
SubResourcePatch: func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
534+
return fmt.Errorf("simulated status patch failure")
535+
},
536+
},
537+
want: errorResult(state.StateCreated),
538+
wantErr: "failed to patch cluster",
516539
},
517540
} {
518541
t.Run(tc.title, func(t *testing.T) {
519-
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, tc.skipStatusSubresource)
542+
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, tc.interceptorFuncs)
520543

521544
flexAPI := mockadmin.NewFlexClustersApi(t)
522545
if tc.atlasUpdateFlexClusterFunc != nil {
@@ -551,13 +574,13 @@ func TestHandleImported(t *testing.T) {
551574
}{
552575
{
553576
title: "no update needed",
554-
flexCluster: withObservedGeneration(
577+
flexCluster: withStateTracker(withObservedGeneration(
555578
withGeneration(
556579
setGroupRef(defaultTestFlexCluster(testClusterName, testNamespace), testGroupName),
557580
1,
558581
),
559582
1,
560-
),
583+
)),
561584
kubeObjects: []client.Object{
562585
defaultTestGroup(testGroupName, testNamespace, pointer.MakePtr(testGroupID)),
563586
},
@@ -585,7 +608,7 @@ func TestHandleImported(t *testing.T) {
585608
},
586609
} {
587610
t.Run(tc.title, func(t *testing.T) {
588-
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, false)
611+
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, nil)
589612

590613
flexAPI := mockadmin.NewFlexClustersApi(t)
591614
if tc.atlasUpdateFlexClusterFunc != nil {
@@ -620,13 +643,13 @@ func TestHandleUpdated(t *testing.T) {
620643
}{
621644
{
622645
title: "no update needed",
623-
flexCluster: withObservedGeneration(
646+
flexCluster: withStateTracker(withObservedGeneration(
624647
withGeneration(
625648
setGroupRef(defaultTestFlexCluster(testClusterName, testNamespace), testGroupName),
626649
1,
627650
),
628651
1,
629-
),
652+
)),
630653
kubeObjects: []client.Object{
631654
defaultTestGroup(testGroupName, testNamespace, pointer.MakePtr(testGroupID)),
632655
},
@@ -654,7 +677,7 @@ func TestHandleUpdated(t *testing.T) {
654677
},
655678
} {
656679
t.Run(tc.title, func(t *testing.T) {
657-
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, false)
680+
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, nil)
658681

659682
flexAPI := mockadmin.NewFlexClustersApi(t)
660683
if tc.atlasUpdateFlexClusterFunc != nil {
@@ -795,7 +818,7 @@ func TestHandleDeletionRequested(t *testing.T) {
795818
},
796819
} {
797820
t.Run(tc.title, func(t *testing.T) {
798-
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, false)
821+
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, nil)
799822

800823
flexAPI := mockadmin.NewFlexClustersApi(t)
801824
if tc.atlasDeleteFlexClusterFunc != nil {
@@ -888,7 +911,7 @@ func TestHandleDeleting(t *testing.T) {
888911
},
889912
} {
890913
t.Run(tc.title, func(t *testing.T) {
891-
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, false)
914+
fakeClient := fixture.buildFakeClient(tc.flexCluster, tc.kubeObjects, nil)
892915

893916
flexAPI := mockadmin.NewFlexClustersApi(t)
894917
if tc.atlasGetFlexClusterFunc != nil {
@@ -930,17 +953,18 @@ func setupTestFixture(t *testing.T) *testFixture {
930953
return fixture
931954
}
932955

933-
// buildFakeClient creates a fake Kubernetes client with the given objects
934-
func (f *testFixture) buildFakeClient(flexCluster *akov2generated.FlexCluster, kubeObjects []client.Object, skipStatusSubresource bool) client.Client {
956+
// buildFakeClient creates a fake Kubernetes client with the given objects and optional interceptor
957+
func (f *testFixture) buildFakeClient(flexCluster *akov2generated.FlexCluster, kubeObjects []client.Object, funcs *interceptor.Funcs) client.Client {
935958
allObjects := kubeObjects
936959
clientBuilder := fake.NewClientBuilder().WithScheme(f.scheme)
937960

961+
if funcs != nil {
962+
clientBuilder = clientBuilder.WithInterceptorFuncs(*funcs)
963+
}
964+
938965
if flexCluster != nil {
939966
allObjects = append([]client.Object{flexCluster}, kubeObjects...)
940-
clientBuilder = clientBuilder.WithObjects(allObjects...)
941-
if !skipStatusSubresource {
942-
clientBuilder = clientBuilder.WithStatusSubresource(flexCluster)
943-
}
967+
clientBuilder = clientBuilder.WithObjects(allObjects...).WithStatusSubresource(flexCluster)
944968
} else {
945969
clientBuilder = clientBuilder.WithObjects(allObjects...)
946970
}
@@ -1117,3 +1141,12 @@ func withResourcePolicyKeep(flexCluster *akov2generated.FlexCluster) *akov2gener
11171141
flexCluster.Annotations["mongodb.com/atlas-resource-policy"] = "keep"
11181142
return flexCluster
11191143
}
1144+
1145+
// withStateTracker adds the state tracker annotation to simulate a previously reconciled object
1146+
func withStateTracker(flexCluster *akov2generated.FlexCluster, deps ...client.Object) *akov2generated.FlexCluster {
1147+
if flexCluster.Annotations == nil {
1148+
flexCluster.Annotations = make(map[string]string)
1149+
}
1150+
flexCluster.Annotations[ctrlstate.AnnotationStateTracker] = ctrlstate.ComputeStateTracker(flexCluster, deps...)
1151+
return flexCluster
1152+
}

0 commit comments

Comments
 (0)