diff --git a/pkg/controller/resourcequota/resource_quota_controller_test.go b/pkg/controller/resourcequota/resource_quota_controller_test.go index 34c3516653d..0077a9380f9 100644 --- a/pkg/controller/resourcequota/resource_quota_controller_test.go +++ b/pkg/controller/resourcequota/resource_quota_controller_test.go @@ -25,7 +25,7 @@ import ( "testing" "time" - v1 "k8s.io/api/core/v1" + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -41,8 +41,6 @@ import ( core "k8s.io/client-go/testing" "k8s.io/client-go/tools/cache" "k8s.io/kubernetes/pkg/controller" - "k8s.io/kubernetes/pkg/quota/v1" - "k8s.io/kubernetes/pkg/quota/v1/generic" "k8s.io/kubernetes/pkg/quota/v1/install" ) diff --git a/pkg/controller/resourcequota/resource_quota_monitor.go b/pkg/controller/resourcequota/resource_quota_monitor.go index fc2ed1bbce8..778e4b464e9 100644 --- a/pkg/controller/resourcequota/resource_quota_monitor.go +++ b/pkg/controller/resourcequota/resource_quota_monitor.go @@ -23,7 +23,7 @@ import ( "k8s.io/klog/v2" - v1 "k8s.io/api/core/v1" + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/clock" diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/resourcequota/BUILD b/staging/src/k8s.io/apiserver/pkg/admission/plugin/resourcequota/BUILD index 20a00652d9b..f181961d86c 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/resourcequota/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/resourcequota/BUILD @@ -59,6 +59,7 @@ go_test( "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission/plugin/resourcequota/apis/resourcequota:go_default_library", "//staging/src/k8s.io/client-go/informers:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/resourcequota/resource_access_test.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/resourcequota/resource_access_test.go index 753bfa73106..48c4583a784 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/resourcequota/resource_access_test.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/resourcequota/resource_access_test.go @@ -22,6 +22,7 @@ import ( "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" lru "github.com/hashicorp/golang-lru" corev1 "k8s.io/api/core/v1" @@ -30,18 +31,6 @@ import ( ) func TestLRUCacheLookup(t *testing.T) { - liveLookupCache, err := lru.New(100) - if err != nil { - t.Fatal(err) - } - kubeClient := fake.NewSimpleClientset() - informerFactory := informers.NewSharedInformerFactory(kubeClient, 0) - - accessor, _ := newQuotaAccessor() - accessor.client = kubeClient - accessor.lister = informerFactory.Core().V1().ResourceQuotas().Lister() - accessor.liveLookupCache = liveLookupCache - namespace := "foo" resourceQuota := &corev1.ResourceQuota{ ObjectMeta: metav1.ObjectMeta{ @@ -50,20 +39,90 @@ func TestLRUCacheLookup(t *testing.T) { }, } - liveLookupCache.Add(resourceQuota.Namespace, liveLookupEntry{expiry: time.Now().Add(30 * time.Second), items: []*corev1.ResourceQuota{ - resourceQuota, - }}) - - quotas, err := accessor.GetQuotas(resourceQuota.Namespace) - if err != nil { - t.Errorf("Unexpected error: %v", err) + testcases := []struct { + description string + cacheInput []*corev1.ResourceQuota + clientInput []runtime.Object + ttl time.Duration + namespace string + expectedQuota *corev1.ResourceQuota + }{ + { + description: "object is found via cache", + cacheInput: []*corev1.ResourceQuota{resourceQuota}, + ttl: 30 * time.Second, + namespace: namespace, + expectedQuota: resourceQuota, + }, + { + description: "object is outdated and not found with client", + cacheInput: []*corev1.ResourceQuota{resourceQuota}, + ttl: -30 * time.Second, + namespace: namespace, + expectedQuota: nil, + }, + { + description: "object is outdated but is found with client", + cacheInput: []*corev1.ResourceQuota{resourceQuota}, + clientInput: []runtime.Object{resourceQuota}, + ttl: -30 * time.Second, + namespace: namespace, + expectedQuota: resourceQuota, + }, + { + description: "object does not exist in cache and is not found with client", + cacheInput: []*corev1.ResourceQuota{resourceQuota}, + ttl: 30 * time.Second, + expectedQuota: nil, + }, + { + description: "object does not exist in cache and is found with client", + cacheInput: []*corev1.ResourceQuota{}, + clientInput: []runtime.Object{resourceQuota}, + namespace: namespace, + expectedQuota: resourceQuota, + }, } - if count := len(quotas); count != 1 { - t.Errorf("Expected 1 object but got %d", count) + for _, tc := range testcases { + t.Run(tc.description, func(t *testing.T) { + liveLookupCache, err := lru.New(1) + if err != nil { + t.Fatal(err) + } + kubeClient := fake.NewSimpleClientset(tc.clientInput...) + informerFactory := informers.NewSharedInformerFactory(kubeClient, 0) + + accessor, _ := newQuotaAccessor() + accessor.client = kubeClient + accessor.lister = informerFactory.Core().V1().ResourceQuotas().Lister() + accessor.liveLookupCache = liveLookupCache + + for _, q := range tc.cacheInput { + quota := q + liveLookupCache.Add(quota.Namespace, liveLookupEntry{expiry: time.Now().Add(tc.ttl), items: []*corev1.ResourceQuota{quota}}) + } + + quotas, err := accessor.GetQuotas(tc.namespace) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + if tc.expectedQuota != nil { + if count := len(quotas); count != 1 { + t.Fatalf("Expected 1 object but got %d", count) + } + + if !reflect.DeepEqual(quotas[0], *tc.expectedQuota) { + t.Errorf("Retrieved object does not match") + } + return + } + + if count := len(quotas); count > 0 { + t.Errorf("Expected 0 objects but got %d", count) + } + }) } - if !reflect.DeepEqual(quotas[0], *resourceQuota) { - t.Errorf("Retrieved object does not match") - } }