1
16
17 package storage
18
19 import (
20 "testing"
21
22 "github.com/google/go-cmp/cmp"
23 apiequality "k8s.io/apimachinery/pkg/api/equality"
24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25 "k8s.io/kubernetes/pkg/apis/autoscaling"
26 api "k8s.io/kubernetes/pkg/apis/core"
27
28
29 _ "k8s.io/api/autoscaling/v1"
30 "k8s.io/apimachinery/pkg/fields"
31 "k8s.io/apimachinery/pkg/labels"
32 "k8s.io/apimachinery/pkg/runtime"
33 genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
34 "k8s.io/apiserver/pkg/registry/generic"
35 genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing"
36 "k8s.io/apiserver/pkg/registry/rest"
37 etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing"
38 "k8s.io/kubernetes/pkg/registry/registrytest"
39 )
40
41 func newStorage(t *testing.T) (*REST, *StatusREST, *etcd3testing.EtcdTestServer) {
42 etcdStorage, server := registrytest.NewEtcdStorage(t, autoscaling.GroupName)
43 restOptions := generic.RESTOptions{
44 StorageConfig: etcdStorage,
45 Decorator: generic.UndecoratedStorage,
46 DeleteCollectionWorkers: 1,
47 ResourcePrefix: "horizontalpodautoscalers",
48 }
49 horizontalPodAutoscalerStorage, statusStorage, err := NewREST(restOptions)
50 if err != nil {
51 t.Fatalf("unexpected error from REST storage: %v", err)
52 }
53 return horizontalPodAutoscalerStorage, statusStorage, server
54 }
55
56 func validNewHorizontalPodAutoscaler(name string) *autoscaling.HorizontalPodAutoscaler {
57 cpu := int32(70)
58 return &autoscaling.HorizontalPodAutoscaler{
59 ObjectMeta: metav1.ObjectMeta{
60 Name: name,
61 Namespace: metav1.NamespaceDefault,
62 },
63 Spec: autoscaling.HorizontalPodAutoscalerSpec{
64 ScaleTargetRef: autoscaling.CrossVersionObjectReference{
65 Kind: "ReplicationController",
66 Name: "myrc",
67 },
68 MaxReplicas: 5,
69 Metrics: []autoscaling.MetricSpec{
70 {
71 Type: autoscaling.ResourceMetricSourceType,
72 Resource: &autoscaling.ResourceMetricSource{
73 Name: api.ResourceCPU,
74 Target: autoscaling.MetricTarget{
75 Type: autoscaling.UtilizationMetricType,
76 AverageUtilization: &cpu,
77 },
78 },
79 },
80 },
81 },
82 }
83 }
84
85 func TestCreate(t *testing.T) {
86 storage, _, server := newStorage(t)
87 defer server.Terminate(t)
88 defer storage.Store.DestroyFunc()
89 test := genericregistrytest.New(t, storage.Store)
90 autoscaler := validNewHorizontalPodAutoscaler("foo")
91 autoscaler.ObjectMeta = metav1.ObjectMeta{}
92 test.TestCreate(
93
94 autoscaler,
95
96 &autoscaling.HorizontalPodAutoscaler{},
97 )
98 }
99
100 func TestUpdate(t *testing.T) {
101 storage, _, server := newStorage(t)
102 defer server.Terminate(t)
103 defer storage.Store.DestroyFunc()
104 test := genericregistrytest.New(t, storage.Store)
105 test.TestUpdate(
106
107 validNewHorizontalPodAutoscaler("foo"),
108
109 func(obj runtime.Object) runtime.Object {
110 object := obj.(*autoscaling.HorizontalPodAutoscaler)
111 object.Spec.MaxReplicas = object.Spec.MaxReplicas + 1
112 return object
113 },
114 )
115 }
116
117 func TestDelete(t *testing.T) {
118 storage, _, server := newStorage(t)
119 defer server.Terminate(t)
120 defer storage.Store.DestroyFunc()
121 test := genericregistrytest.New(t, storage.Store)
122 test.TestDelete(validNewHorizontalPodAutoscaler("foo"))
123 }
124
125 func TestGet(t *testing.T) {
126 storage, _, server := newStorage(t)
127 defer server.Terminate(t)
128 defer storage.Store.DestroyFunc()
129 test := genericregistrytest.New(t, storage.Store)
130 test.TestGet(validNewHorizontalPodAutoscaler("foo"))
131 }
132
133 func TestList(t *testing.T) {
134 storage, _, server := newStorage(t)
135 defer server.Terminate(t)
136 defer storage.Store.DestroyFunc()
137 test := genericregistrytest.New(t, storage.Store)
138 test.TestList(validNewHorizontalPodAutoscaler("foo"))
139 }
140
141 func TestWatch(t *testing.T) {
142 storage, _, server := newStorage(t)
143 defer server.Terminate(t)
144 defer storage.Store.DestroyFunc()
145 test := genericregistrytest.New(t, storage.Store)
146 test.TestWatch(
147 validNewHorizontalPodAutoscaler("foo"),
148
149 []labels.Set{},
150
151 []labels.Set{
152 {"foo": "bar"},
153 },
154
155 []fields.Set{},
156
157 []fields.Set{
158 {"metadata.name": "bar"},
159 {"name": "foo"},
160 },
161 )
162 }
163
164 func TestShortNames(t *testing.T) {
165 storage, _, server := newStorage(t)
166 defer server.Terminate(t)
167 defer storage.Store.DestroyFunc()
168 expected := []string{"hpa"}
169 registrytest.AssertShortNames(t, storage, expected)
170 }
171
172 func TestCategories(t *testing.T) {
173 storage, _, server := newStorage(t)
174 defer server.Terminate(t)
175 defer storage.Store.DestroyFunc()
176 expected := []string{"all"}
177 registrytest.AssertCategories(t, storage, expected)
178 }
179
180 func TestUpdateStatus(t *testing.T) {
181 storage, statusStorage, server := newStorage(t)
182 defer server.Terminate(t)
183 defer storage.Store.DestroyFunc()
184 ctx := genericapirequest.NewDefaultContext()
185 key, _ := storage.KeyFunc(ctx, "foo")
186 autoscalerStart := validNewHorizontalPodAutoscaler("foo")
187 err := storage.Storage.Create(ctx, key, autoscalerStart, nil, 0, false)
188 if err != nil {
189 t.Errorf("unexpected error: %v", err)
190 }
191
192 autoscalerIn := &autoscaling.HorizontalPodAutoscaler{
193 ObjectMeta: metav1.ObjectMeta{
194 Name: "foo",
195 Namespace: metav1.NamespaceDefault,
196 },
197 Status: autoscaling.HorizontalPodAutoscalerStatus{
198 Conditions: []autoscaling.HorizontalPodAutoscalerCondition{
199 {Status: "True"},
200 },
201 },
202 }
203
204 _, _, err = statusStorage.Update(ctx, autoscalerIn.Name, rest.DefaultUpdatedObjectInfo(autoscalerIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{})
205 if err != nil {
206 t.Fatalf("Unexpected error: %v", err)
207 }
208 obj, err := storage.Get(ctx, "foo", &metav1.GetOptions{})
209 if err != nil {
210 t.Fatalf("Unexpected error: %v", err)
211 }
212 autoscalerOut := obj.(*autoscaling.HorizontalPodAutoscaler)
213
214 if !apiequality.Semantic.DeepEqual(autoscalerIn.Status, autoscalerOut.Status) {
215 t.Errorf("unexpected object: %s", cmp.Diff(autoscalerIn, autoscalerOut))
216 }
217 }
218
View as plain text