From 4a89500478ec62f47f7da35f6e023b6fea4555b1 Mon Sep 17 00:00:00 2001 From: Andrew Sy Kim Date: Fri, 14 Oct 2022 16:00:58 -0400 Subject: [PATCH 1/2] add unit tests for apiserverleasegc controller Signed-off-by: Andrew Sy Kim --- .../apiserverleasegc/gc_controller_test.go | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 pkg/controlplane/controller/apiserverleasegc/gc_controller_test.go diff --git a/pkg/controlplane/controller/apiserverleasegc/gc_controller_test.go b/pkg/controlplane/controller/apiserverleasegc/gc_controller_test.go new file mode 100644 index 00000000000..76fe4c2a49b --- /dev/null +++ b/pkg/controlplane/controller/apiserverleasegc/gc_controller_test.go @@ -0,0 +1,153 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apiserverleasegc + +import ( + "context" + "testing" + "time" + + coordinationv1 "k8s.io/api/coordination/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" + testingclock "k8s.io/utils/clock/testing" + "k8s.io/utils/pointer" +) + +func Test_Controller(t *testing.T) { + fakeClock := testingclock.NewFakeClock(time.Now()) + tests := []struct { + name string + lease *coordinationv1.Lease + expectDeleted bool + }{ + { + name: "lease not expired", + lease: &coordinationv1.Lease{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kube-apiserver-12345", + Namespace: metav1.NamespaceSystem, + Labels: map[string]string{ + "k8s.io/component": "kube-apiserver", + }, + }, + Spec: coordinationv1.LeaseSpec{ + HolderIdentity: pointer.StringPtr("kube-apiserver-12345"), + LeaseDurationSeconds: pointer.Int32Ptr(10), + RenewTime: &metav1.MicroTime{Time: fakeClock.Now()}, + }, + }, + expectDeleted: false, + }, + { + name: "expired lease but with a different component label", + lease: &coordinationv1.Lease{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kube-apiserver-12345", + Namespace: metav1.NamespaceSystem, + Labels: map[string]string{ + "k8s.io/component": "kube-controller-manager", + }, + }, + Spec: coordinationv1.LeaseSpec{ + HolderIdentity: pointer.StringPtr("kube-apiserver-12345"), + LeaseDurationSeconds: pointer.Int32Ptr(10), + RenewTime: &metav1.MicroTime{Time: fakeClock.Now().Add(-time.Minute)}, + }, + }, + expectDeleted: false, + }, + { + name: "lease expired due to expired renew time", + lease: &coordinationv1.Lease{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kube-apiserver-12345", + Namespace: metav1.NamespaceSystem, + Labels: map[string]string{ + "k8s.io/component": "kube-apiserver", + }, + }, + Spec: coordinationv1.LeaseSpec{ + HolderIdentity: pointer.StringPtr("kube-apiserver-12345"), + LeaseDurationSeconds: pointer.Int32Ptr(10), + RenewTime: &metav1.MicroTime{Time: fakeClock.Now().Add(-time.Minute)}, + }, + }, + expectDeleted: true, + }, + { + name: "lease expired due to nil renew time", + lease: &coordinationv1.Lease{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kube-apiserver-12345", + Namespace: metav1.NamespaceSystem, + Labels: map[string]string{ + "k8s.io/component": "kube-apiserver", + }, + }, + Spec: coordinationv1.LeaseSpec{ + HolderIdentity: pointer.StringPtr("kube-apiserver-12345"), + LeaseDurationSeconds: pointer.Int32Ptr(10), + RenewTime: nil, + }, + }, + expectDeleted: true, + }, + { + name: "lease expired due to nil lease duration seconds", + lease: &coordinationv1.Lease{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kube-apiserver-12345", + Namespace: metav1.NamespaceSystem, + Labels: map[string]string{ + "k8s.io/component": "kube-apiserver", + }, + }, + Spec: coordinationv1.LeaseSpec{ + HolderIdentity: pointer.StringPtr("kube-apiserver-12345"), + LeaseDurationSeconds: nil, + RenewTime: &metav1.MicroTime{Time: fakeClock.Now().Add(-time.Minute)}, + }, + }, + expectDeleted: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + clientset := fake.NewSimpleClientset(test.lease) + controller := NewAPIServerLeaseGC(clientset, 100*time.Millisecond, metav1.NamespaceSystem, "k8s.io/component=kube-apiserver") + go controller.Run(nil) + + time.Sleep(1 * time.Second) + + _, err := clientset.CoordinationV1().Leases(test.lease.Namespace).Get(context.TODO(), test.lease.Name, metav1.GetOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + t.Errorf("unexpected error %v", err) + } + + if apierrors.IsNotFound(err) && !test.expectDeleted { + t.Errorf("lease was not deleted") + } + + if err == nil && test.expectDeleted { + t.Error("lease was not deleted") + } + }) + } +} From c4c867dd96bb29a2d045ba45cc67a86d5b7a7845 Mon Sep 17 00:00:00 2001 From: Andrew Sy Kim Date: Tue, 18 Oct 2022 20:40:21 -0400 Subject: [PATCH 2/2] add comments for Test_Controller in pkg/controlplane/controller/apiserverleasegc Signed-off-by: Andrew Sy Kim --- .../controller/apiserverleasegc/gc_controller_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/controlplane/controller/apiserverleasegc/gc_controller_test.go b/pkg/controlplane/controller/apiserverleasegc/gc_controller_test.go index 76fe4c2a49b..0e86e70ff9f 100644 --- a/pkg/controlplane/controller/apiserverleasegc/gc_controller_test.go +++ b/pkg/controlplane/controller/apiserverleasegc/gc_controller_test.go @@ -29,6 +29,7 @@ import ( "k8s.io/utils/pointer" ) +// Test_Controller validates the garbage collection logic for the apiserverleasegc controller. func Test_Controller(t *testing.T) { fakeClock := testingclock.NewFakeClock(time.Now()) tests := []struct { @@ -134,7 +135,7 @@ func Test_Controller(t *testing.T) { controller := NewAPIServerLeaseGC(clientset, 100*time.Millisecond, metav1.NamespaceSystem, "k8s.io/component=kube-apiserver") go controller.Run(nil) - time.Sleep(1 * time.Second) + time.Sleep(time.Second) _, err := clientset.CoordinationV1().Leases(test.lease.Namespace).Get(context.TODO(), test.lease.Name, metav1.GetOptions{}) if err != nil && !apierrors.IsNotFound(err) {