Skip to content

Commit 47d8c08

Browse files
committed
Get test coverage for controller/source package to 100%
1 parent 1d1e5af commit 47d8c08

File tree

3 files changed

+255
-25
lines changed

3 files changed

+255
-25
lines changed

pkg/controller/source/internal/internal_test.go

Lines changed: 200 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ limitations under the License.
1717
package internal_test
1818

1919
import (
20-
"time"
21-
2220
"github.com/kubernetes-sigs/controller-runtime/pkg/controller/event"
2321
"github.com/kubernetes-sigs/controller-runtime/pkg/controller/eventhandler"
2422
"github.com/kubernetes-sigs/controller-runtime/pkg/controller/source/internal"
@@ -28,13 +26,19 @@ import (
2826
"k8s.io/client-go/tools/cache"
2927
"k8s.io/client-go/util/workqueue"
3028

29+
"github.com/kubernetes-sigs/controller-runtime/pkg/controller/controllertest"
30+
"github.com/kubernetes-sigs/controller-runtime/pkg/controller/predicate"
3131
corev1 "k8s.io/api/core/v1"
32+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
33+
"k8s.io/apimachinery/pkg/runtime"
34+
"k8s.io/apimachinery/pkg/runtime/schema"
3235
)
3336

3437
var _ = Describe("Internal", func() {
3538

3639
var instance internal.EventHandler
37-
var funcs *eventhandler.Funcs
40+
var funcs, setfuncs *eventhandler.Funcs
41+
var set bool
3842
BeforeEach(func() {
3943
funcs = &eventhandler.Funcs{
4044
CreateFunc: func(workqueue.RateLimitingInterface, event.CreateEvent) {
@@ -54,8 +58,23 @@ var _ = Describe("Internal", func() {
5458
Fail("Did not expect GenericEvent to be called.")
5559
},
5660
}
61+
62+
setfuncs = &eventhandler.Funcs{
63+
CreateFunc: func(workqueue.RateLimitingInterface, event.CreateEvent) {
64+
set = true
65+
},
66+
DeleteFunc: func(q workqueue.RateLimitingInterface, e event.DeleteEvent) {
67+
set = true
68+
},
69+
UpdateFunc: func(workqueue.RateLimitingInterface, event.UpdateEvent) {
70+
set = true
71+
},
72+
GenericFunc: func(workqueue.RateLimitingInterface, event.GenericEvent) {
73+
set = true
74+
},
75+
}
5776
instance = internal.EventHandler{
58-
Queue: Queue{},
77+
Queue: controllertest.Queue{},
5978
EventHandler: funcs,
6079
}
6180
})
@@ -86,6 +105,63 @@ var _ = Describe("Internal", func() {
86105
close(done)
87106
})
88107

108+
It("should used Predicates to filter CreateEvents", func(done Done) {
109+
instance = internal.EventHandler{
110+
Queue: controllertest.Queue{},
111+
EventHandler: setfuncs,
112+
}
113+
114+
set = false
115+
instance.Predicates = []predicate.Predicate{
116+
predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return false }},
117+
}
118+
instance.OnAdd(pod)
119+
Expect(set).To(BeFalse())
120+
121+
set = false
122+
instance.Predicates = []predicate.Predicate{
123+
predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }},
124+
}
125+
instance.OnAdd(pod)
126+
Expect(set).To(BeTrue())
127+
128+
set = false
129+
instance.Predicates = []predicate.Predicate{
130+
predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }},
131+
predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return false }},
132+
}
133+
instance.OnAdd(pod)
134+
Expect(set).To(BeFalse())
135+
136+
set = false
137+
instance.Predicates = []predicate.Predicate{
138+
predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return false }},
139+
predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }},
140+
}
141+
instance.OnAdd(pod)
142+
Expect(set).To(BeFalse())
143+
144+
set = false
145+
instance.Predicates = []predicate.Predicate{
146+
predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }},
147+
predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }},
148+
}
149+
instance.OnAdd(pod)
150+
Expect(set).To(BeTrue())
151+
152+
close(done)
153+
})
154+
155+
It("should not call Create EventHandler if the object is not a runtime.Object", func(done Done) {
156+
instance.OnAdd(&metav1.ObjectMeta{})
157+
close(done)
158+
})
159+
160+
It("should not call Create EventHandler if the object does not have metadata", func(done Done) {
161+
instance.OnAdd(FooRuntimeObject{})
162+
close(done)
163+
})
164+
89165
It("should create an UpdateEvent", func(done Done) {
90166
funcs.UpdateFunc = func(q workqueue.RateLimitingInterface, evt event.UpdateEvent) {
91167
defer GinkgoRecover()
@@ -105,6 +181,65 @@ var _ = Describe("Internal", func() {
105181
close(done)
106182
})
107183

184+
It("should used Predicates to filter UpdateEvents", func(done Done) {
185+
instance = internal.EventHandler{
186+
Queue: controllertest.Queue{},
187+
EventHandler: setfuncs,
188+
}
189+
190+
set = false
191+
instance.Predicates = []predicate.Predicate{
192+
predicate.Funcs{UpdateFunc: func(updateEvent event.UpdateEvent) bool { return false }},
193+
}
194+
instance.OnUpdate(pod, newPod)
195+
Expect(set).To(BeFalse())
196+
197+
set = false
198+
instance.Predicates = []predicate.Predicate{
199+
predicate.Funcs{UpdateFunc: func(event.UpdateEvent) bool { return true }},
200+
}
201+
instance.OnUpdate(pod, newPod)
202+
Expect(set).To(BeTrue())
203+
204+
set = false
205+
instance.Predicates = []predicate.Predicate{
206+
predicate.Funcs{UpdateFunc: func(event.UpdateEvent) bool { return true }},
207+
predicate.Funcs{UpdateFunc: func(event.UpdateEvent) bool { return false }},
208+
}
209+
instance.OnUpdate(pod, newPod)
210+
Expect(set).To(BeFalse())
211+
212+
set = false
213+
instance.Predicates = []predicate.Predicate{
214+
predicate.Funcs{UpdateFunc: func(event.UpdateEvent) bool { return false }},
215+
predicate.Funcs{UpdateFunc: func(event.UpdateEvent) bool { return true }},
216+
}
217+
instance.OnUpdate(pod, newPod)
218+
Expect(set).To(BeFalse())
219+
220+
set = false
221+
instance.Predicates = []predicate.Predicate{
222+
predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }},
223+
predicate.Funcs{CreateFunc: func(event.CreateEvent) bool { return true }},
224+
}
225+
instance.OnUpdate(pod, newPod)
226+
Expect(set).To(BeTrue())
227+
228+
close(done)
229+
})
230+
231+
It("should not call Update EventHandler if the object is not a runtime.Object", func(done Done) {
232+
instance.OnUpdate(&metav1.ObjectMeta{}, &corev1.Pod{})
233+
instance.OnUpdate(&corev1.Pod{}, &metav1.ObjectMeta{})
234+
close(done)
235+
})
236+
237+
It("should not call Update EventHandler if the object does not have metadata", func(done Done) {
238+
instance.OnUpdate(FooRuntimeObject{}, &corev1.Pod{})
239+
instance.OnUpdate(&corev1.Pod{}, FooRuntimeObject{})
240+
close(done)
241+
})
242+
108243
It("should create a DeleteEvent", func(done Done) {
109244
funcs.DeleteFunc = func(q workqueue.RateLimitingInterface, evt event.DeleteEvent) {
110245
defer GinkgoRecover()
@@ -119,6 +254,63 @@ var _ = Describe("Internal", func() {
119254
close(done)
120255
})
121256

257+
It("should used Predicates to filter DeleteEvents", func(done Done) {
258+
instance = internal.EventHandler{
259+
Queue: controllertest.Queue{},
260+
EventHandler: setfuncs,
261+
}
262+
263+
set = false
264+
instance.Predicates = []predicate.Predicate{
265+
predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return false }},
266+
}
267+
instance.OnDelete(pod)
268+
Expect(set).To(BeFalse())
269+
270+
set = false
271+
instance.Predicates = []predicate.Predicate{
272+
predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return true }},
273+
}
274+
instance.OnDelete(pod)
275+
Expect(set).To(BeTrue())
276+
277+
set = false
278+
instance.Predicates = []predicate.Predicate{
279+
predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return true }},
280+
predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return false }},
281+
}
282+
instance.OnDelete(pod)
283+
Expect(set).To(BeFalse())
284+
285+
set = false
286+
instance.Predicates = []predicate.Predicate{
287+
predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return false }},
288+
predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return true }},
289+
}
290+
instance.OnDelete(pod)
291+
Expect(set).To(BeFalse())
292+
293+
set = false
294+
instance.Predicates = []predicate.Predicate{
295+
predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return true }},
296+
predicate.Funcs{DeleteFunc: func(event.DeleteEvent) bool { return true }},
297+
}
298+
instance.OnDelete(pod)
299+
Expect(set).To(BeTrue())
300+
301+
close(done)
302+
})
303+
304+
It("should not call Delete EventHandler if the object is not a runtime.Object", func(done Done) {
305+
instance.OnDelete(&metav1.ObjectMeta{})
306+
close(done)
307+
})
308+
309+
It("should not call Delete EventHandler if the object does not have metadata", func(done Done) {
310+
instance.OnDelete(FooRuntimeObject{})
311+
close(done)
312+
})
313+
122314
It("should create a DeleteEvent from a tombstone", func(done Done) {
123315

124316
tombstone := cache.DeletedFinalStateUnknown{
@@ -153,25 +345,9 @@ var _ = Describe("Internal", func() {
153345

154346
type Foo struct{}
155347

156-
var _ workqueue.RateLimitingInterface = Queue{}
157-
158-
type Queue struct {
159-
workqueue.Interface
160-
}
161-
162-
// AddAfter adds an item to the workqueue after the indicated duration has passed
163-
func (q Queue) AddAfter(item interface{}, duration time.Duration) {
164-
q.Add(item)
165-
}
166-
167-
func (q Queue) AddRateLimited(item interface{}) {
168-
q.Add(item)
169-
}
348+
var _ runtime.Object = FooRuntimeObject{}
170349

171-
func (q Queue) Forget(item interface{}) {
172-
// Do nothing
173-
}
350+
type FooRuntimeObject struct{}
174351

175-
func (q Queue) NumRequeues(item interface{}) int {
176-
return 0
177-
}
352+
func (FooRuntimeObject) GetObjectKind() schema.ObjectKind { return nil }
353+
func (FooRuntimeObject) DeepCopyObject() runtime.Object { return nil }

pkg/controller/source/source.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func (ks *KindSource) Start(handler eventhandler.EventHandler, queue workqueue.R
8686

8787
// informers should have been injected before Start was called
8888
if ks.informers == nil {
89-
return fmt.Errorf("must call DoInformers on KindSource before calling Start")
89+
return fmt.Errorf("must call InjectInformers on KindSource before calling Start")
9090
}
9191

9292
// Lookup the Informer from the Informers and add an EventHandler which populates the Queue

pkg/controller/source/source_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
. "github.com/onsi/gomega"
2929
"k8s.io/client-go/util/workqueue"
3030

31+
"github.com/kubernetes-sigs/controller-runtime/pkg/controller/predicate"
3132
corev1 "k8s.io/api/core/v1"
3233
)
3334

@@ -187,6 +188,26 @@ var _ = Describe("Source", func() {
187188
close(done)
188189
})
189190
})
191+
192+
It("should return an error from Start if informers were not injected", func(done Done) {
193+
instance := source.KindSource{Type: &corev1.Pod{}}
194+
err := instance.Start(nil, nil)
195+
Expect(err).To(HaveOccurred())
196+
Expect(err.Error()).To(ContainSubstring("must call InjectInformers on KindSource before calling Start"))
197+
198+
close(done)
199+
})
200+
201+
It("should return an error from Start if a type was not provided", func(done Done) {
202+
instance := source.KindSource{}
203+
instance.InjectInformers(&informertest.FakeInformers{})
204+
err := instance.Start(nil, nil)
205+
Expect(err).To(HaveOccurred())
206+
Expect(err.Error()).To(ContainSubstring("must specify KindSource.Type"))
207+
208+
close(done)
209+
})
210+
190211
Context("for a Kind not in the cache", func() {
191212
It("should return an error when Start is called", func(done Done) {
192213
ic.Error = fmt.Errorf("test error")
@@ -203,4 +224,37 @@ var _ = Describe("Source", func() {
203224
})
204225
})
205226
})
227+
228+
Describe("Func", func() {
229+
It("should be called from Start", func(done Done) {
230+
run := false
231+
instance := source.Func(func(
232+
eventhandler.EventHandler,
233+
workqueue.RateLimitingInterface, ...predicate.Predicate) error {
234+
run = true
235+
return nil
236+
})
237+
Expect(instance.Start(nil, nil)).NotTo(HaveOccurred())
238+
Expect(run).To(BeTrue())
239+
240+
expected := fmt.Errorf("expected error: Func")
241+
instance = source.Func(func(
242+
eventhandler.EventHandler,
243+
workqueue.RateLimitingInterface, ...predicate.Predicate) error {
244+
return expected
245+
})
246+
Expect(instance.Start(nil, nil)).To(Equal(expected))
247+
248+
close(done)
249+
})
250+
})
251+
252+
Describe("ChannelSource", func() {
253+
It("TODO(community): implement this", func(done Done) {
254+
instance := source.ChannelSource(make(chan event.GenericEvent))
255+
instance.Start(nil, nil)
256+
257+
close(done)
258+
})
259+
})
206260
})

0 commit comments

Comments
 (0)