mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 08:17:26 +00:00
196 lines
9.2 KiB
Go
196 lines
9.2 KiB
Go
/*
|
|
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 legacytokentracking
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"golang.org/x/time/rate"
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
"k8s.io/client-go/kubernetes/fake"
|
|
core "k8s.io/client-go/testing"
|
|
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
|
"k8s.io/kubernetes/pkg/features"
|
|
testingclock "k8s.io/utils/clock/testing"
|
|
)
|
|
|
|
const throttlePeriod = 30 * time.Second
|
|
|
|
func TestSyncConfigMap(t *testing.T) {
|
|
now := time.Now().UTC()
|
|
tests := []struct {
|
|
name string
|
|
enabled bool
|
|
nextCreateAt []time.Time
|
|
clientObjects []runtime.Object
|
|
existingConfigMap *corev1.ConfigMap
|
|
|
|
expectedErr error
|
|
expectedActions []core.Action
|
|
}{
|
|
{
|
|
name: "create configmap [no cache, no live object]",
|
|
enabled: true,
|
|
clientObjects: []runtime.Object{},
|
|
expectedActions: []core.Action{
|
|
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "configmaps"}, metav1.NamespaceSystem, &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)}}),
|
|
},
|
|
},
|
|
{
|
|
name: "create configmap should ignore AlreadyExists error [no cache, live object exists]",
|
|
enabled: true,
|
|
clientObjects: []runtime.Object{
|
|
&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)}},
|
|
},
|
|
expectedActions: []core.Action{
|
|
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "configmaps"}, metav1.NamespaceSystem, &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)}}),
|
|
},
|
|
},
|
|
{
|
|
name: "create configmap throttled [no cache, no live object]",
|
|
enabled: true,
|
|
nextCreateAt: []time.Time{now.Add(throttlePeriod - 2*time.Second), now.Add(throttlePeriod - time.Second)},
|
|
clientObjects: []runtime.Object{},
|
|
expectedActions: []core.Action{
|
|
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "configmaps"}, metav1.NamespaceSystem, &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)}}),
|
|
},
|
|
},
|
|
{
|
|
name: "create configmap after throttle period [no cache, no live object]",
|
|
enabled: true,
|
|
nextCreateAt: []time.Time{now.Add(throttlePeriod - 2*time.Second), now.Add(throttlePeriod - time.Second), now.Add(throttlePeriod + time.Second)},
|
|
clientObjects: []runtime.Object{},
|
|
expectedActions: []core.Action{
|
|
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "configmaps"}, metav1.NamespaceSystem, &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)}}),
|
|
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "configmaps"}, metav1.NamespaceSystem, &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Add(throttlePeriod + time.Second).Format(dateFormat)}}),
|
|
},
|
|
},
|
|
{
|
|
name: "skip update configmap [cache with expected date format exists, live object exists]",
|
|
enabled: true,
|
|
clientObjects: []runtime.Object{
|
|
&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)}},
|
|
},
|
|
existingConfigMap: &corev1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName},
|
|
Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)},
|
|
},
|
|
expectedActions: []core.Action{},
|
|
},
|
|
{
|
|
name: "update configmap [cache with unexpected date format, live object exists]",
|
|
enabled: true,
|
|
clientObjects: []runtime.Object{
|
|
&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(time.RFC3339)}},
|
|
},
|
|
existingConfigMap: &corev1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName},
|
|
Data: map[string]string{ConfigMapDataKey: now.Format(time.RFC3339)},
|
|
},
|
|
expectedActions: []core.Action{
|
|
core.NewUpdateAction(schema.GroupVersionResource{Version: "v1", Resource: "configmaps"}, metav1.NamespaceSystem, &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)}}),
|
|
},
|
|
},
|
|
{
|
|
name: "update configmap should ignore NotFound error [cache with unexpected date format, no live object]",
|
|
enabled: true,
|
|
existingConfigMap: &corev1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName},
|
|
Data: map[string]string{ConfigMapDataKey: "BAD_TIMESTAMP"},
|
|
},
|
|
expectedActions: []core.Action{
|
|
core.NewUpdateAction(schema.GroupVersionResource{Version: "v1", Resource: "configmaps"}, metav1.NamespaceSystem, &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)}}),
|
|
},
|
|
},
|
|
{
|
|
name: "delete configmap [no cache, no live object]",
|
|
expectedActions: []core.Action{},
|
|
},
|
|
{
|
|
name: "delete configmap [cache exists, live object exists]",
|
|
clientObjects: []runtime.Object{
|
|
&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(time.RFC3339)}},
|
|
},
|
|
existingConfigMap: &corev1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName},
|
|
Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)},
|
|
},
|
|
expectedActions: []core.Action{
|
|
core.NewDeleteAction(schema.GroupVersionResource{Version: "v1", Resource: "configmaps"}, metav1.NamespaceSystem, ConfigMapName),
|
|
},
|
|
},
|
|
{
|
|
name: "delete configmap that's alrady being deleted [cache exists, live object exists]",
|
|
clientObjects: []runtime.Object{
|
|
&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(time.RFC3339)}},
|
|
},
|
|
existingConfigMap: &corev1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName, DeletionTimestamp: &metav1.Time{Time: time.Now()}},
|
|
Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)},
|
|
},
|
|
expectedActions: []core.Action{},
|
|
},
|
|
{
|
|
name: "delete configmap should ignore NotFound error [cache exists, no live object]",
|
|
existingConfigMap: &corev1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName},
|
|
Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)},
|
|
},
|
|
expectedActions: []core.Action{
|
|
core.NewDeleteAction(schema.GroupVersionResource{Version: "v1", Resource: "configmaps"}, metav1.NamespaceSystem, ConfigMapName),
|
|
},
|
|
},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LegacyServiceAccountTokenTracking, test.enabled)()
|
|
|
|
client := fake.NewSimpleClientset(test.clientObjects...)
|
|
limiter := rate.NewLimiter(rate.Every(throttlePeriod), 1)
|
|
controller := newController(client, testingclock.NewFakeClock(now), limiter)
|
|
if test.existingConfigMap != nil {
|
|
controller.configMapCache.Add(test.existingConfigMap)
|
|
}
|
|
|
|
if err := controller.syncConfigMap(); err != nil {
|
|
t.Errorf("Failed to sync ConfigMap, err: %v", err)
|
|
}
|
|
|
|
for _, createAt := range test.nextCreateAt {
|
|
// delete the existing configmap to trigger second create
|
|
controller.configMapCache.Delete(&corev1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName},
|
|
})
|
|
controller.clock.(*testingclock.FakeClock).SetTime(createAt)
|
|
if err := controller.syncConfigMap(); err != nil {
|
|
t.Errorf("Failed to sync ConfigMap, err: %v", err)
|
|
}
|
|
}
|
|
|
|
if diff := cmp.Diff(test.expectedActions, client.Actions()); diff != "" {
|
|
t.Errorf("Unexpected diff (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|