1
16
17 package legacytokentracking
18
19 import (
20 "testing"
21 "time"
22
23 "github.com/google/go-cmp/cmp"
24 "golang.org/x/time/rate"
25
26 corev1 "k8s.io/api/core/v1"
27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28 "k8s.io/apimachinery/pkg/runtime"
29 "k8s.io/apimachinery/pkg/runtime/schema"
30 "k8s.io/client-go/kubernetes/fake"
31 core "k8s.io/client-go/testing"
32 testingclock "k8s.io/utils/clock/testing"
33 )
34
35 const throttlePeriod = 30 * time.Second
36
37 func TestSyncConfigMap(t *testing.T) {
38 now := time.Now().UTC()
39 tests := []struct {
40 name string
41 nextCreateAt []time.Time
42 clientObjects []runtime.Object
43 existingConfigMap *corev1.ConfigMap
44
45 expectedErr error
46 expectedActions []core.Action
47 }{
48 {
49 name: "create configmap [no cache, no live object]",
50 clientObjects: []runtime.Object{},
51 expectedActions: []core.Action{
52 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)}}),
53 },
54 },
55 {
56 name: "create configmap should ignore AlreadyExists error [no cache, live object exists]",
57 clientObjects: []runtime.Object{
58 &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)}},
59 },
60 expectedActions: []core.Action{
61 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)}}),
62 },
63 },
64 {
65 name: "create configmap throttled [no cache, no live object]",
66 nextCreateAt: []time.Time{now.Add(throttlePeriod - 2*time.Second), now.Add(throttlePeriod - time.Second)},
67 clientObjects: []runtime.Object{},
68 expectedActions: []core.Action{
69 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)}}),
70 },
71 },
72 {
73 name: "create configmap after throttle period [no cache, no live object]",
74 nextCreateAt: []time.Time{now.Add(throttlePeriod - 2*time.Second), now.Add(throttlePeriod - time.Second), now.Add(throttlePeriod + time.Second)},
75 clientObjects: []runtime.Object{},
76 expectedActions: []core.Action{
77 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)}}),
78 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)}}),
79 },
80 },
81 {
82 name: "skip update configmap [cache with expected date format exists, live object exists]",
83 clientObjects: []runtime.Object{
84 &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)}},
85 },
86 existingConfigMap: &corev1.ConfigMap{
87 ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName},
88 Data: map[string]string{ConfigMapDataKey: now.Format(dateFormat)},
89 },
90 expectedActions: []core.Action{},
91 },
92 {
93 name: "update configmap [cache with unexpected date format, live object exists]",
94 clientObjects: []runtime.Object{
95 &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: map[string]string{ConfigMapDataKey: now.Format(time.RFC3339)}},
96 },
97 existingConfigMap: &corev1.ConfigMap{
98 ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName},
99 Data: map[string]string{ConfigMapDataKey: now.Format(time.RFC3339)},
100 },
101 expectedActions: []core.Action{
102 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)}}),
103 },
104 },
105 {
106 name: "update configmap with no data",
107 clientObjects: []runtime.Object{
108 &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName}, Data: nil},
109 },
110 existingConfigMap: &corev1.ConfigMap{
111 ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName},
112 Data: nil,
113 },
114 expectedActions: []core.Action{
115 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)}}),
116 },
117 },
118 {
119 name: "update configmap should ignore NotFound error [cache with unexpected date format, no live object]",
120 existingConfigMap: &corev1.ConfigMap{
121 ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName},
122 Data: map[string]string{ConfigMapDataKey: "BAD_TIMESTAMP"},
123 },
124 expectedActions: []core.Action{
125 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)}}),
126 },
127 },
128 }
129 for _, test := range tests {
130 t.Run(test.name, func(t *testing.T) {
131 client := fake.NewSimpleClientset(test.clientObjects...)
132 limiter := rate.NewLimiter(rate.Every(throttlePeriod), 1)
133 controller := newController(client, testingclock.NewFakeClock(now), limiter)
134 if test.existingConfigMap != nil {
135 controller.configMapCache.Add(test.existingConfigMap)
136 }
137
138 if err := controller.syncConfigMap(); err != nil {
139 t.Errorf("Failed to sync ConfigMap, err: %v", err)
140 }
141
142 for _, createAt := range test.nextCreateAt {
143
144 controller.configMapCache.Delete(&corev1.ConfigMap{
145 ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: ConfigMapName},
146 })
147 controller.clock.(*testingclock.FakeClock).SetTime(createAt)
148 if err := controller.syncConfigMap(); err != nil {
149 t.Errorf("Failed to sync ConfigMap, err: %v", err)
150 }
151 }
152
153 if diff := cmp.Diff(test.expectedActions, client.Actions()); diff != "" {
154 t.Errorf("Unexpected diff (-want +got):\n%s", diff)
155 }
156 })
157 }
158 }
159
View as plain text