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  }