k8s.io/kubernetes@v1.29.3/pkg/controller/statefulset/stateful_set_status_updater_test.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package statefulset 18 19 import ( 20 "context" 21 "errors" 22 "testing" 23 24 apps "k8s.io/api/apps/v1" 25 apierrors "k8s.io/apimachinery/pkg/api/errors" 26 "k8s.io/apimachinery/pkg/runtime" 27 "k8s.io/client-go/kubernetes/fake" 28 appslisters "k8s.io/client-go/listers/apps/v1" 29 core "k8s.io/client-go/testing" 30 "k8s.io/client-go/tools/cache" 31 ) 32 33 func TestStatefulSetUpdaterUpdatesSetStatus(t *testing.T) { 34 set := newStatefulSet(3) 35 status := apps.StatefulSetStatus{ObservedGeneration: 1, Replicas: 2} 36 fakeClient := &fake.Clientset{} 37 updater := NewRealStatefulSetStatusUpdater(fakeClient, nil) 38 fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) { 39 update := action.(core.UpdateAction) 40 return true, update.GetObject(), nil 41 }) 42 if err := updater.UpdateStatefulSetStatus(context.TODO(), set, &status); err != nil { 43 t.Errorf("Error returned on successful status update: %s", err) 44 } 45 if set.Status.Replicas != 2 { 46 t.Errorf("UpdateStatefulSetStatus mutated the sets replicas %d", set.Status.Replicas) 47 } 48 } 49 50 func TestStatefulSetStatusUpdaterUpdatesObservedGeneration(t *testing.T) { 51 set := newStatefulSet(3) 52 status := apps.StatefulSetStatus{ObservedGeneration: 3, Replicas: 2} 53 fakeClient := &fake.Clientset{} 54 updater := NewRealStatefulSetStatusUpdater(fakeClient, nil) 55 fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) { 56 update := action.(core.UpdateAction) 57 sts := update.GetObject().(*apps.StatefulSet) 58 if sts.Status.ObservedGeneration != 3 { 59 t.Errorf("expected observedGeneration to be synced with generation for statefulset %q", sts.Name) 60 } 61 return true, sts, nil 62 }) 63 if err := updater.UpdateStatefulSetStatus(context.TODO(), set, &status); err != nil { 64 t.Errorf("Error returned on successful status update: %s", err) 65 } 66 } 67 68 func TestStatefulSetStatusUpdaterUpdateReplicasFailure(t *testing.T) { 69 set := newStatefulSet(3) 70 status := apps.StatefulSetStatus{ObservedGeneration: 3, Replicas: 2} 71 fakeClient := &fake.Clientset{} 72 indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) 73 indexer.Add(set) 74 setLister := appslisters.NewStatefulSetLister(indexer) 75 updater := NewRealStatefulSetStatusUpdater(fakeClient, setLister) 76 fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) { 77 return true, nil, apierrors.NewInternalError(errors.New("API server down")) 78 }) 79 if err := updater.UpdateStatefulSetStatus(context.TODO(), set, &status); err == nil { 80 t.Error("Failed update did not return error") 81 } 82 } 83 84 func TestStatefulSetStatusUpdaterUpdateReplicasConflict(t *testing.T) { 85 set := newStatefulSet(3) 86 status := apps.StatefulSetStatus{ObservedGeneration: 3, Replicas: 2} 87 conflict := false 88 fakeClient := &fake.Clientset{} 89 indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) 90 indexer.Add(set) 91 setLister := appslisters.NewStatefulSetLister(indexer) 92 updater := NewRealStatefulSetStatusUpdater(fakeClient, setLister) 93 fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) { 94 update := action.(core.UpdateAction) 95 if !conflict { 96 conflict = true 97 return true, update.GetObject(), apierrors.NewConflict(action.GetResource().GroupResource(), set.Name, errors.New("object already exists")) 98 } 99 return true, update.GetObject(), nil 100 101 }) 102 if err := updater.UpdateStatefulSetStatus(context.TODO(), set, &status); err != nil { 103 t.Errorf("UpdateStatefulSetStatus returned an error: %s", err) 104 } 105 if set.Status.Replicas != 2 { 106 t.Errorf("UpdateStatefulSetStatus mutated the sets replicas %d", set.Status.Replicas) 107 } 108 } 109 110 func TestStatefulSetStatusUpdaterUpdateReplicasConflictFailure(t *testing.T) { 111 set := newStatefulSet(3) 112 status := apps.StatefulSetStatus{ObservedGeneration: 3, Replicas: 2} 113 fakeClient := &fake.Clientset{} 114 indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) 115 indexer.Add(set) 116 setLister := appslisters.NewStatefulSetLister(indexer) 117 updater := NewRealStatefulSetStatusUpdater(fakeClient, setLister) 118 fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) { 119 update := action.(core.UpdateAction) 120 return true, update.GetObject(), apierrors.NewConflict(action.GetResource().GroupResource(), set.Name, errors.New("object already exists")) 121 }) 122 if err := updater.UpdateStatefulSetStatus(context.TODO(), set, &status); err == nil { 123 t.Error("UpdateStatefulSetStatus failed to return an error on get failure") 124 } 125 } 126 127 func TestStatefulSetStatusUpdaterGetAvailableReplicas(t *testing.T) { 128 set := newStatefulSet(3) 129 status := apps.StatefulSetStatus{ObservedGeneration: 1, Replicas: 2, AvailableReplicas: 3} 130 fakeClient := &fake.Clientset{} 131 updater := NewRealStatefulSetStatusUpdater(fakeClient, nil) 132 fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) { 133 update := action.(core.UpdateAction) 134 return true, update.GetObject(), nil 135 }) 136 if err := updater.UpdateStatefulSetStatus(context.TODO(), set, &status); err != nil { 137 t.Errorf("Error returned on successful status update: %s", err) 138 } 139 if set.Status.AvailableReplicas != 3 { 140 t.Errorf("UpdateStatefulSetStatus mutated the sets replicas %d", set.Status.AvailableReplicas) 141 } 142 }