k8s.io/kubernetes@v1.29.3/pkg/registry/resource/podschedulingcontext/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: "podschedulingcontexts", 45 } 46 podSchedulingStorage, statusStorage, err := NewREST(restOptions) 47 if err != nil { 48 t.Fatalf("unexpected error from REST storage: %v", err) 49 } 50 return podSchedulingStorage, statusStorage, server 51 } 52 53 func validNewPodSchedulingContexts(name, ns string) *resource.PodSchedulingContext { 54 schedulingCtx := &resource.PodSchedulingContext{ 55 ObjectMeta: metav1.ObjectMeta{ 56 Name: name, 57 Namespace: ns, 58 }, 59 Spec: resource.PodSchedulingContextSpec{ 60 SelectedNode: "worker", 61 }, 62 Status: resource.PodSchedulingContextStatus{}, 63 } 64 return schedulingCtx 65 } 66 67 func TestCreate(t *testing.T) { 68 storage, _, server := newStorage(t) 69 defer server.Terminate(t) 70 defer storage.Store.DestroyFunc() 71 test := genericregistrytest.New(t, storage.Store) 72 schedulingCtx := validNewPodSchedulingContexts("foo", metav1.NamespaceDefault) 73 schedulingCtx.ObjectMeta = metav1.ObjectMeta{} 74 test.TestCreate( 75 // valid 76 schedulingCtx, 77 // invalid 78 &resource.PodSchedulingContext{ 79 ObjectMeta: metav1.ObjectMeta{Name: "*BadName!"}, 80 }, 81 ) 82 } 83 84 func TestUpdate(t *testing.T) { 85 storage, _, server := newStorage(t) 86 defer server.Terminate(t) 87 defer storage.Store.DestroyFunc() 88 test := genericregistrytest.New(t, storage.Store) 89 test.TestUpdate( 90 // valid 91 validNewPodSchedulingContexts("foo", metav1.NamespaceDefault), 92 // updateFunc 93 func(obj runtime.Object) runtime.Object { 94 object := obj.(*resource.PodSchedulingContext) 95 if object.Labels == nil { 96 object.Labels = map[string]string{} 97 } 98 object.Labels["foo"] = "bar" 99 return object 100 }, 101 ) 102 } 103 104 func TestDelete(t *testing.T) { 105 storage, _, server := newStorage(t) 106 defer server.Terminate(t) 107 defer storage.Store.DestroyFunc() 108 test := genericregistrytest.New(t, storage.Store).ReturnDeletedObject() 109 test.TestDelete(validNewPodSchedulingContexts("foo", metav1.NamespaceDefault)) 110 } 111 112 func TestGet(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) 117 test.TestGet(validNewPodSchedulingContexts("foo", metav1.NamespaceDefault)) 118 } 119 120 func TestList(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.TestList(validNewPodSchedulingContexts("foo", metav1.NamespaceDefault)) 126 } 127 128 func TestWatch(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.TestWatch( 134 validNewPodSchedulingContexts("foo", metav1.NamespaceDefault), 135 // matching labels 136 []labels.Set{}, 137 // not matching labels 138 []labels.Set{ 139 {"foo": "bar"}, 140 }, 141 // matching fields 142 []fields.Set{ 143 {"metadata.name": "foo"}, 144 }, 145 // not matching fields 146 []fields.Set{ 147 {"metadata.name": "bar"}, 148 }, 149 ) 150 } 151 152 func TestUpdateStatus(t *testing.T) { 153 storage, statusStorage, server := newStorage(t) 154 defer server.Terminate(t) 155 defer storage.Store.DestroyFunc() 156 ctx := genericapirequest.NewDefaultContext() 157 158 key, _ := storage.KeyFunc(ctx, "foo") 159 schedulingStart := validNewPodSchedulingContexts("foo", metav1.NamespaceDefault) 160 err := storage.Storage.Create(ctx, key, schedulingStart, nil, 0, false) 161 if err != nil { 162 t.Fatalf("Unexpected error: %v", err) 163 } 164 165 schedulingCtx := schedulingStart.DeepCopy() 166 schedulingCtx.Status.ResourceClaims = append(schedulingCtx.Status.ResourceClaims, 167 resource.ResourceClaimSchedulingStatus{ 168 Name: "my-claim", 169 }, 170 ) 171 _, _, err = statusStorage.Update(ctx, schedulingCtx.Name, rest.DefaultUpdatedObjectInfo(schedulingCtx), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) 172 if err != nil { 173 t.Fatalf("Unexpected error: %v", err) 174 } 175 obj, err := storage.Get(ctx, "foo", &metav1.GetOptions{}) 176 if err != nil { 177 t.Errorf("unexpected error: %v", err) 178 } 179 schedulingOut := obj.(*resource.PodSchedulingContext) 180 // only compare relevant changes b/c of difference in metadata 181 if !apiequality.Semantic.DeepEqual(schedulingCtx.Status, schedulingOut.Status) { 182 t.Errorf("unexpected object: %s", cmp.Diff(schedulingCtx.Status, schedulingOut.Status)) 183 } 184 }