1
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 }
143
View as plain text