k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/registry/core/resourcequota/storage/storage_test.go (about) 1 /* 2 Copyright 2015 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 storage 18 19 import ( 20 "testing" 21 22 "github.com/google/go-cmp/cmp" 23 apiequality "k8s.io/apimachinery/pkg/api/equality" 24 "k8s.io/apimachinery/pkg/api/resource" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 "k8s.io/apimachinery/pkg/fields" 27 "k8s.io/apimachinery/pkg/labels" 28 genericapirequest "k8s.io/apiserver/pkg/endpoints/request" 29 "k8s.io/apiserver/pkg/registry/generic" 30 genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing" 31 "k8s.io/apiserver/pkg/registry/rest" 32 etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" 33 api "k8s.io/kubernetes/pkg/apis/core" 34 "k8s.io/kubernetes/pkg/registry/registrytest" 35 ) 36 37 func newStorage(t *testing.T) (*REST, *StatusREST, *etcd3testing.EtcdTestServer) { 38 etcdStorage, server := registrytest.NewEtcdStorage(t, "") 39 restOptions := generic.RESTOptions{ 40 StorageConfig: etcdStorage, 41 Decorator: generic.UndecoratedStorage, 42 DeleteCollectionWorkers: 1, 43 ResourcePrefix: "resourcequotas", 44 } 45 resourceQuotaStorage, statusStorage, err := NewREST(restOptions) 46 if err != nil { 47 t.Fatalf("unexpected error from REST storage: %v", err) 48 } 49 return resourceQuotaStorage, statusStorage, server 50 } 51 52 func validNewResourceQuota() *api.ResourceQuota { 53 return &api.ResourceQuota{ 54 ObjectMeta: metav1.ObjectMeta{ 55 Name: "foo", 56 Namespace: metav1.NamespaceDefault, 57 }, 58 Spec: api.ResourceQuotaSpec{ 59 Hard: api.ResourceList{ 60 api.ResourceCPU: resource.MustParse("100"), 61 api.ResourceMemory: resource.MustParse("4Gi"), 62 api.ResourcePods: resource.MustParse("10"), 63 api.ResourceServices: resource.MustParse("10"), 64 api.ResourceReplicationControllers: resource.MustParse("10"), 65 api.ResourceQuotas: resource.MustParse("1"), 66 }, 67 }, 68 } 69 } 70 71 func TestCreate(t *testing.T) { 72 storage, _, server := newStorage(t) 73 defer server.Terminate(t) 74 defer storage.Store.DestroyFunc() 75 test := genericregistrytest.New(t, storage.Store) 76 resourcequota := validNewResourceQuota() 77 resourcequota.ObjectMeta = metav1.ObjectMeta{} 78 test.TestCreate( 79 // valid 80 resourcequota, 81 // invalid 82 &api.ResourceQuota{ 83 ObjectMeta: metav1.ObjectMeta{Name: "_-a123-a_"}, 84 }, 85 ) 86 } 87 88 func TestCreateSetsFields(t *testing.T) { 89 storage, _, server := newStorage(t) 90 defer server.Terminate(t) 91 defer storage.Store.DestroyFunc() 92 ctx := genericapirequest.NewDefaultContext() 93 resourcequota := validNewResourceQuota() 94 _, err := storage.Create(genericapirequest.NewDefaultContext(), resourcequota, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) 95 if err != nil { 96 t.Fatalf("unexpected error: %v", err) 97 } 98 99 object, err := storage.Get(ctx, "foo", &metav1.GetOptions{}) 100 if err != nil { 101 t.Errorf("unexpected error: %v", err) 102 } 103 actual := object.(*api.ResourceQuota) 104 if actual.Name != resourcequota.Name { 105 t.Errorf("unexpected resourcequota: %#v", actual) 106 } 107 if len(actual.UID) == 0 { 108 t.Errorf("expected resourcequota UID to be set: %#v", actual) 109 } 110 } 111 112 func TestDelete(t *testing.T) { 113 storage, _, server := newStorage(t) 114 defer server.Terminate(t) 115 defer storage.Store.DestroyFunc() 116 test := genericregistrytest.New(t, storage.Store).ReturnDeletedObject() 117 test.TestDelete(validNewResourceQuota()) 118 } 119 120 func TestGet(t *testing.T) { 121 storage, _, server := newStorage(t) 122 defer server.Terminate(t) 123 defer storage.Store.DestroyFunc() 124 test := genericregistrytest.New(t, storage.Store) 125 test.TestGet(validNewResourceQuota()) 126 } 127 128 func TestList(t *testing.T) { 129 storage, _, server := newStorage(t) 130 defer server.Terminate(t) 131 defer storage.Store.DestroyFunc() 132 test := genericregistrytest.New(t, storage.Store) 133 test.TestList(validNewResourceQuota()) 134 } 135 136 func TestWatch(t *testing.T) { 137 storage, _, server := newStorage(t) 138 defer server.Terminate(t) 139 defer storage.Store.DestroyFunc() 140 test := genericregistrytest.New(t, storage.Store) 141 test.TestWatch( 142 validNewResourceQuota(), 143 // matching labels 144 []labels.Set{}, 145 // not matching labels 146 []labels.Set{ 147 {"foo": "bar"}, 148 }, 149 // matching fields 150 []fields.Set{ 151 {"metadata.name": "foo"}, 152 }, 153 // not matching fields 154 []fields.Set{ 155 {"metadata.name": "bar"}, 156 }, 157 ) 158 } 159 160 func TestUpdateStatus(t *testing.T) { 161 storage, status, server := newStorage(t) 162 defer server.Terminate(t) 163 defer storage.Store.DestroyFunc() 164 ctx := genericapirequest.NewDefaultContext() 165 166 key, _ := storage.KeyFunc(ctx, "foo") 167 resourcequotaStart := validNewResourceQuota() 168 err := storage.Storage.Create(ctx, key, resourcequotaStart, nil, 0, false) 169 if err != nil { 170 t.Fatalf("Unexpected error: %v", err) 171 } 172 173 resourcequotaIn := &api.ResourceQuota{ 174 ObjectMeta: metav1.ObjectMeta{ 175 Name: "foo", 176 Namespace: metav1.NamespaceDefault, 177 }, 178 Status: api.ResourceQuotaStatus{ 179 Used: api.ResourceList{ 180 api.ResourceCPU: resource.MustParse("1"), 181 api.ResourceMemory: resource.MustParse("1Gi"), 182 api.ResourcePods: resource.MustParse("1"), 183 api.ResourceServices: resource.MustParse("1"), 184 api.ResourceReplicationControllers: resource.MustParse("1"), 185 api.ResourceQuotas: resource.MustParse("1"), 186 }, 187 Hard: api.ResourceList{ 188 api.ResourceCPU: resource.MustParse("100"), 189 api.ResourceMemory: resource.MustParse("4Gi"), 190 api.ResourcePods: resource.MustParse("10"), 191 api.ResourceServices: resource.MustParse("10"), 192 api.ResourceReplicationControllers: resource.MustParse("10"), 193 api.ResourceQuotas: resource.MustParse("1"), 194 }, 195 }, 196 } 197 198 _, _, err = status.Update(ctx, resourcequotaIn.Name, rest.DefaultUpdatedObjectInfo(resourcequotaIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) 199 if err != nil { 200 t.Fatalf("Unexpected error: %v", err) 201 } 202 obj, err := storage.Get(ctx, "foo", &metav1.GetOptions{}) 203 if err != nil { 204 t.Fatalf("Unexpected error: %v", err) 205 } 206 rqOut := obj.(*api.ResourceQuota) 207 // only compare the meaningful update b/c we can't compare due to metadata 208 if !apiequality.Semantic.DeepEqual(resourcequotaIn.Status, rqOut.Status) { 209 t.Errorf("unexpected object: %s", cmp.Diff(resourcequotaIn, rqOut)) 210 } 211 } 212 213 func TestShortNames(t *testing.T) { 214 storage, _, server := newStorage(t) 215 defer server.Terminate(t) 216 defer storage.Store.DestroyFunc() 217 expected := []string{"quota"} 218 registrytest.AssertShortNames(t, storage, expected) 219 }