Skip to content

Commit d5362cf

Browse files
authored
Add test for InstrumentedEnqueueRequestForObject (#15)
* Add test for InstrumentedEnqueueRequestForObject * Verify metric values * Add contexts for the delete case * Fix composite literal uses unkeyed fields error
1 parent 2fbf2f8 commit d5362cf

File tree

3 files changed

+230
-2
lines changed

3 files changed

+230
-2
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/onsi/ginkgo v1.12.1
77
github.com/onsi/gomega v1.10.1
88
github.com/prometheus/client_golang v1.0.0
9+
github.com/prometheus/client_model v0.2.0
910
github.com/stretchr/testify v1.5.1
1011
k8s.io/api v0.18.4
1112
k8s.io/apimachinery v0.18.4

handler/handler_suite_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ import (
1919

2020
. "github.com/onsi/ginkgo"
2121
. "github.com/onsi/gomega"
22-
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
2322
)
2423

2524
func TestEventhandler(t *testing.T) {
2625
RegisterFailHandler(Fail)
27-
RunSpecsWithDefaultAndCustomReporters(t, "Handler Suite", []Reporter{printer.NewlineReporter{}})
26+
RunSpecs(t, "Handler Suite")
2827
}
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
// Copyright 2020 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package handler
16+
17+
import (
18+
. "github.com/onsi/ginkgo"
19+
. "github.com/onsi/gomega"
20+
dto "github.com/prometheus/client_model/go"
21+
corev1 "k8s.io/api/core/v1"
22+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
"k8s.io/apimachinery/pkg/types"
24+
"sigs.k8s.io/controller-runtime/pkg/controller/controllertest"
25+
"sigs.k8s.io/controller-runtime/pkg/event"
26+
"sigs.k8s.io/controller-runtime/pkg/metrics"
27+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
28+
29+
"k8s.io/client-go/util/workqueue"
30+
)
31+
32+
var _ = Describe("InstrumentedEnqueueRequestForObject", func() {
33+
var q workqueue.RateLimitingInterface
34+
var instance InstrumentedEnqueueRequestForObject
35+
var pod *corev1.Pod
36+
37+
BeforeEach(func() {
38+
q = controllertest.Queue{Interface: workqueue.New()}
39+
instance = InstrumentedEnqueueRequestForObject{}
40+
pod = &corev1.Pod{
41+
TypeMeta: metav1.TypeMeta{
42+
Kind: "Pod",
43+
APIVersion: "v1",
44+
},
45+
ObjectMeta: metav1.ObjectMeta{
46+
Namespace: "biznamespace",
47+
Name: "bizname",
48+
CreationTimestamp: metav1.Now(),
49+
},
50+
}
51+
})
52+
Describe("Create", func() {
53+
It("should enqueue a request & emit a metric on a CreateEvent", func() {
54+
evt := event.CreateEvent{
55+
Object: pod,
56+
Meta: pod.GetObjectMeta(),
57+
}
58+
59+
// test the create
60+
instance.Create(evt, q)
61+
62+
// verify workqueue
63+
Expect(q.Len()).To(Equal(1))
64+
i, _ := q.Get()
65+
Expect(i).To(Equal(reconcile.Request{
66+
NamespacedName: types.NamespacedName{
67+
Namespace: pod.Namespace,
68+
Name: pod.Name,
69+
},
70+
}))
71+
72+
// verify metrics
73+
gauges, err := metrics.Registry.Gather()
74+
Expect(err).NotTo(HaveOccurred())
75+
Expect(len(gauges)).To(Equal(1))
76+
assertMetrics(gauges[0], 1, []*corev1.Pod{pod})
77+
})
78+
})
79+
80+
Describe("Delete", func() {
81+
Context("when a gauge already exists", func() {
82+
BeforeEach(func() {
83+
evt := event.CreateEvent{
84+
Object: pod,
85+
Meta: pod.GetObjectMeta(),
86+
}
87+
instance.Create(evt, q)
88+
Expect(q.Len()).To(Equal(1))
89+
})
90+
It("should enqueue a request & remove the metric on a DeleteEvent", func() {
91+
evt := event.DeleteEvent{
92+
Object: pod,
93+
Meta: pod.GetObjectMeta(),
94+
}
95+
96+
// test the delete
97+
instance.Delete(evt, q)
98+
99+
// verify workqueue
100+
Expect(q.Len()).To(Equal(1))
101+
i, _ := q.Get()
102+
Expect(i).To(Equal(reconcile.Request{
103+
NamespacedName: types.NamespacedName{
104+
Namespace: pod.Namespace,
105+
Name: pod.Name,
106+
},
107+
}))
108+
109+
// verify metrics
110+
gauges, err := metrics.Registry.Gather()
111+
Expect(err).NotTo(HaveOccurred())
112+
Expect(len(gauges)).To(Equal(0))
113+
})
114+
})
115+
Context("when a gauge does not exist", func() {
116+
It("should enqueue a request & there should be no new metric on a DeleteEvent", func() {
117+
evt := event.DeleteEvent{
118+
Object: pod,
119+
Meta: pod.GetObjectMeta(),
120+
}
121+
122+
// test the delete
123+
instance.Delete(evt, q)
124+
125+
// verify workqueue
126+
Expect(q.Len()).To(Equal(1))
127+
i, _ := q.Get()
128+
Expect(i).To(Equal(reconcile.Request{
129+
NamespacedName: types.NamespacedName{
130+
Namespace: pod.Namespace,
131+
Name: pod.Name,
132+
},
133+
}))
134+
135+
// verify metrics
136+
gauges, err := metrics.Registry.Gather()
137+
Expect(err).NotTo(HaveOccurred())
138+
Expect(len(gauges)).To(Equal(0))
139+
})
140+
})
141+
142+
})
143+
144+
Describe("Update", func() {
145+
It("should enqueue a request in case of UpdateEvent", func() {
146+
newpod := &corev1.Pod{
147+
ObjectMeta: metav1.ObjectMeta{
148+
Namespace: "baznamespace",
149+
Name: "bazname",
150+
},
151+
}
152+
evt := event.UpdateEvent{
153+
ObjectOld: pod,
154+
MetaOld: pod.GetObjectMeta(),
155+
ObjectNew: newpod,
156+
MetaNew: newpod.GetObjectMeta(),
157+
}
158+
159+
// test the update
160+
instance.Update(evt, q)
161+
162+
// verify workqueue
163+
Expect(q.Len()).To(Equal(2))
164+
i, _ := q.Get()
165+
Expect(i).To(Equal(reconcile.Request{
166+
NamespacedName: types.NamespacedName{
167+
Namespace: pod.Namespace,
168+
Name: pod.Name,
169+
},
170+
}))
171+
i, _ = q.Get()
172+
Expect(i).To(Equal(reconcile.Request{
173+
NamespacedName: types.NamespacedName{
174+
Namespace: newpod.Namespace,
175+
Name: newpod.Name,
176+
},
177+
}))
178+
179+
// verify metrics
180+
gauges, err := metrics.Registry.Gather()
181+
Expect(err).NotTo(HaveOccurred())
182+
Expect(len(gauges)).To(Equal(1))
183+
assertMetrics(gauges[0], 2, []*corev1.Pod{newpod, pod})
184+
})
185+
})
186+
187+
Describe("getResourceLabels", func() {
188+
It("should fill out map with values from given objects", func() {
189+
labelMap := getResourceLabels(pod.GetObjectMeta(), pod)
190+
Expect(labelMap).ShouldNot(BeEmpty())
191+
Expect(len(labelMap)).To(Equal(5))
192+
Expect(labelMap["name"]).To(Equal(pod.GetObjectMeta().GetName()))
193+
Expect(labelMap["namespace"]).To(Equal(pod.GetObjectMeta().GetNamespace()))
194+
Expect(labelMap["group"]).To(Equal(pod.GetObjectKind().GroupVersionKind().Group))
195+
Expect(labelMap["version"]).To(Equal(pod.GetObjectKind().GroupVersionKind().Version))
196+
Expect(labelMap["kind"]).To(Equal(pod.GetObjectKind().GroupVersionKind().Kind))
197+
})
198+
})
199+
})
200+
201+
func assertMetrics(gauge *dto.MetricFamily, count int, pods []*corev1.Pod) {
202+
// need variables to compare the pointers
203+
name := "name"
204+
namespace := "namespace"
205+
g := "group"
206+
v := "version"
207+
k := "kind"
208+
209+
Expect(len(gauge.Metric)).To(Equal(count))
210+
for i := 0; i < count; i++ {
211+
Expect(*gauge.Metric[i].Gauge.Value).To(Equal(float64(pods[i].GetObjectMeta().GetCreationTimestamp().UTC().Unix())))
212+
213+
for _, l := range gauge.Metric[i].Label {
214+
switch l.Name {
215+
case &name:
216+
Expect(l.Value).To(Equal(pods[i].GetObjectMeta().GetName()))
217+
case &namespace:
218+
Expect(l.Value).To(Equal(pods[i].GetObjectMeta().GetNamespace()))
219+
case &g:
220+
Expect(l.Value).To(Equal(pods[i].GetObjectKind().GroupVersionKind().Group))
221+
case &v:
222+
Expect(l.Value).To(Equal(pods[i].GetObjectKind().GroupVersionKind().Version))
223+
case &k:
224+
Expect(l.Value).To(Equal(pods[i].GetObjectKind().GroupVersionKind().Kind))
225+
}
226+
}
227+
}
228+
}

0 commit comments

Comments
 (0)