integration test

This commit is contained in:
Haowei Cai 2020-11-10 15:12:33 -08:00
parent 1d43fd4694
commit 4794ba18ed

View File

@ -22,6 +22,8 @@ import (
"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/apimachinery/pkg/util/wait"
"k8s.io/apiserver/pkg/features"
@ -31,9 +33,12 @@ import (
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
"k8s.io/kubernetes/pkg/controlplane"
"k8s.io/kubernetes/test/integration/framework"
"k8s.io/utils/pointer"
)
const apiserverIdentityLeaseLabelSelector = controlplane.IdentityLeaseComponentLabelKey + "=" + controlplane.KubeAPIServer
const (
testLeaseName = "apiserver-lease-test"
)
func TestCreateLeaseOnStart(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.APIServerIdentity, true)()
@ -50,7 +55,7 @@ func TestCreateLeaseOnStart(t *testing.T) {
leases, err := kubeclient.
CoordinationV1().
Leases(metav1.NamespaceSystem).
List(context.TODO(), metav1.ListOptions{LabelSelector: apiserverIdentityLeaseLabelSelector})
List(context.TODO(), metav1.ListOptions{LabelSelector: controlplane.KubeAPIServerIdentityLeaseLabelSelector})
if err != nil {
return false, err
}
@ -62,3 +67,99 @@ func TestCreateLeaseOnStart(t *testing.T) {
t.Fatalf("Failed to see the kube-apiserver lease: %v", err)
}
}
func TestLeaseGarbageCollection(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.APIServerIdentity, true)()
result := kubeapiservertesting.StartTestServerOrDie(t, nil,
// This shorten the GC check period to make the test run faster.
// Since we are testing GC behavior on leases we create, what happens to
// the real apiserver lease doesn't matter.
[]string{"--identity-lease-duration-seconds=1"},
framework.SharedEtcd())
defer result.TearDownFn()
kubeclient, err := kubernetes.NewForConfig(result.ClientConfig)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
expiredLease := newTestLease(time.Now().Add(-2*time.Hour), metav1.NamespaceSystem)
t.Run("expired apiserver lease should be garbage collected",
testLeaseGarbageCollected(t, kubeclient, expiredLease))
freshLease := newTestLease(time.Now().Add(-2*time.Minute), metav1.NamespaceSystem)
t.Run("fresh apiserver lease should not be garbage collected",
testLeaseNotGarbageCollected(t, kubeclient, freshLease))
expiredLease.Labels = nil
t.Run("expired non-identity lease should not be garbage collected",
testLeaseNotGarbageCollected(t, kubeclient, expiredLease))
// identity leases (with k8s.io/component label) created in user namespaces should not be GC'ed
expiredNonKubeSystemLease := newTestLease(time.Now().Add(-2*time.Hour), metav1.NamespaceDefault)
t.Run("expired non-system identity lease should not be garbage collected",
testLeaseNotGarbageCollected(t, kubeclient, expiredNonKubeSystemLease))
}
func testLeaseGarbageCollected(t *testing.T, client kubernetes.Interface, lease *coordinationv1.Lease) func(t *testing.T) {
return func(t *testing.T) {
ns := lease.Namespace
if _, err := client.CoordinationV1().Leases(ns).Create(context.TODO(), lease, metav1.CreateOptions{}); err != nil {
t.Fatalf("Unexpected error creating lease: %v", err)
}
if err := wait.PollImmediate(500*time.Millisecond, 5*time.Second, func() (bool, error) {
_, err := client.CoordinationV1().Leases(ns).Get(context.TODO(), lease.Name, metav1.GetOptions{})
if err == nil {
return false, nil
}
if apierrors.IsNotFound(err) {
return true, nil
}
return false, err
}); err != nil {
t.Fatalf("Failed to see the expired lease garbage collected: %v", err)
}
}
}
func testLeaseNotGarbageCollected(t *testing.T, client kubernetes.Interface, lease *coordinationv1.Lease) func(t *testing.T) {
return func(t *testing.T) {
ns := lease.Namespace
if _, err := client.CoordinationV1().Leases(ns).Create(context.TODO(), lease, metav1.CreateOptions{}); err != nil {
t.Fatalf("Unexpected error creating lease: %v", err)
}
if err := wait.PollImmediate(500*time.Millisecond, 5*time.Second, func() (bool, error) {
_, err := client.CoordinationV1().Leases(ns).Get(context.TODO(), lease.Name, metav1.GetOptions{})
if err != nil && apierrors.IsNotFound(err) {
return true, nil
}
return false, nil
}); err == nil {
t.Fatalf("Unexpected valid lease getting garbage collected")
}
if _, err := client.CoordinationV1().Leases(ns).Get(context.TODO(), lease.Name, metav1.GetOptions{}); err != nil {
t.Fatalf("Failed to retrieve valid lease: %v", err)
}
if err := client.CoordinationV1().Leases(ns).Delete(context.TODO(), lease.Name, metav1.DeleteOptions{}); err != nil {
t.Fatalf("Failed to clean up valid lease: %v", err)
}
}
}
func newTestLease(acquireTime time.Time, namespace string) *coordinationv1.Lease {
return &coordinationv1.Lease{
ObjectMeta: metav1.ObjectMeta{
Name: testLeaseName,
Namespace: namespace,
Labels: map[string]string{
controlplane.IdentityLeaseComponentLabelKey: controlplane.KubeAPIServer,
},
},
Spec: coordinationv1.LeaseSpec{
HolderIdentity: pointer.StringPtr(testLeaseName),
LeaseDurationSeconds: pointer.Int32Ptr(3600),
AcquireTime: &metav1.MicroTime{Time: acquireTime},
RenewTime: &metav1.MicroTime{Time: acquireTime},
},
}
}