k8s.io/kubernetes@v1.29.3/pkg/registry/resource/resourceclaim/storage/storage_test.go (about) 1 /* 2 Copyright 2022 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 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/fields" 26 "k8s.io/apimachinery/pkg/labels" 27 "k8s.io/apimachinery/pkg/runtime" 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 "k8s.io/kubernetes/pkg/apis/resource" 34 _ "k8s.io/kubernetes/pkg/apis/resource/install" 35 "k8s.io/kubernetes/pkg/registry/registrytest" 36 ) 37 38 func newStorage(t *testing.T) (*REST, *StatusREST, *etcd3testing.EtcdTestServer) { 39 etcdStorage, server := registrytest.NewEtcdStorage(t, resource.GroupName) 40 restOptions := generic.RESTOptions{ 41 StorageConfig: etcdStorage, 42 Decorator: generic.UndecoratedStorage, 43 DeleteCollectionWorkers: 1, 44 ResourcePrefix: "resourceclaims", 45 } 46 resourceClaimStorage, statusStorage, err := NewREST(restOptions) 47 if err != nil { 48 t.Fatalf("unexpected error from REST storage: %v", err) 49 } 50 return resourceClaimStorage, statusStorage, server 51 } 52 53 func validNewClaim(name, ns string) *resource.ResourceClaim { 54 claim := &resource.ResourceClaim{ 55 ObjectMeta: metav1.ObjectMeta{ 56 Name: name, 57 Namespace: ns, 58 }, 59 Spec: resource.ResourceClaimSpec{ 60 ResourceClassName: "example", 61 AllocationMode: resource.AllocationModeImmediate, 62 }, 63 Status: resource.ResourceClaimStatus{}, 64 } 65 return claim 66 } 67 68 func TestCreate(t *testing.T) { 69 storage, _, server := newStorage(t) 70 defer server.Terminate(t) 71 defer storage.Store.DestroyFunc() 72 test := genericregistrytest.New(t, storage.Store) 73 claim := validNewClaim("foo", metav1.NamespaceDefault) 74 claim.ObjectMeta = metav1.ObjectMeta{} 75 test.TestCreate( 76 // valid 77 claim, 78 // invalid 79 &resource.ResourceClaim{ 80 ObjectMeta: metav1.ObjectMeta{Name: "*BadName!"}, 81 }, 82 ) 83 } 84 85 func TestUpdate(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 test.TestUpdate( 91 // valid 92 validNewClaim("foo", metav1.NamespaceDefault), 93 // updateFunc 94 func(obj runtime.Object) runtime.Object { 95 object := obj.(*resource.ResourceClaim) 96 if object.Labels == nil { 97 object.Labels = map[string]string{} 98 } 99 object.Labels["foo"] = "bar" 100 return object 101 }, 102 ) 103 } 104 105 func TestDelete(t *testing.T) { 106 storage, _, server := newStorage(t) 107 defer server.Terminate(t) 108 defer storage.Store.DestroyFunc() 109 test := genericregistrytest.New(t, storage.Store).ReturnDeletedObject() 110 test.TestDelete(validNewClaim("foo", metav1.NamespaceDefault)) 111 } 112 113 func TestGet(t *testing.T) { 114 storage, _, server := newStorage(t) 115 defer server.Terminate(t) 116 defer storage.Store.DestroyFunc() 117 test := genericregistrytest.New(t, storage.Store) 118 test.TestGet(validNewClaim("foo", metav1.NamespaceDefault)) 119 } 120 121 func TestList(t *testing.T) { 122 storage, _, server := newStorage(t) 123 defer server.Terminate(t) 124 defer storage.Store.DestroyFunc() 125 test := genericregistrytest.New(t, storage.Store) 126 test.TestList(validNewClaim("foo", metav1.NamespaceDefault)) 127 } 128 129 func TestWatch(t *testing.T) { 130 storage, _, server := newStorage(t) 131 defer server.Terminate(t) 132 defer storage.Store.DestroyFunc() 133 test := genericregistrytest.New(t, storage.Store) 134 test.TestWatch( 135 validNewClaim("foo", metav1.NamespaceDefault), 136 // matching labels 137 []labels.Set{}, 138 // not matching labels 139 []labels.Set{ 140 {"foo": "bar"}, 141 }, 142 // matching fields 143 []fields.Set{ 144 {"metadata.name": "foo"}, 145 }, 146 // not matching fields 147 []fields.Set{ 148 {"metadata.name": "bar"}, 149 }, 150 ) 151 } 152 153 func TestUpdateStatus(t *testing.T) { 154 storage, statusStorage, server := newStorage(t) 155 defer server.Terminate(t) 156 defer storage.Store.DestroyFunc() 157 ctx := genericapirequest.NewDefaultContext() 158 159 key, _ := storage.KeyFunc(ctx, "foo") 160 claimStart := validNewClaim("foo", metav1.NamespaceDefault) 161 err := storage.Storage.Create(ctx, key, claimStart, nil, 0, false) 162 if err != nil { 163 t.Fatalf("Unexpected error: %v", err) 164 } 165 166 claim := claimStart.DeepCopy() 167 claim.Status.DriverName = "some-driver.example.com" 168 claim.Status.Allocation = &resource.AllocationResult{} 169 _, _, err = statusStorage.Update(ctx, claim.Name, rest.DefaultUpdatedObjectInfo(claim), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) 170 if err != nil { 171 t.Fatalf("Unexpected error: %v", err) 172 } 173 obj, err := storage.Get(ctx, "foo", &metav1.GetOptions{}) 174 if err != nil { 175 t.Errorf("unexpected error: %v", err) 176 } 177 claimOut := obj.(*resource.ResourceClaim) 178 // only compare relevant changes b/c of difference in metadata 179 if !apiequality.Semantic.DeepEqual(claim.Status, claimOut.Status) { 180 t.Errorf("unexpected object: %s", cmp.Diff(claim.Status, claimOut.Status)) 181 } 182 }