Skip to content

Commit 8752ba7

Browse files
committed
harden handler validation logic, add tests for it to ensure it works appropriately
Signed-off-by: everettraven <[email protected]>
1 parent daf9fb4 commit 8752ba7

File tree

1 file changed

+52
-19
lines changed

1 file changed

+52
-19
lines changed

pkg/reconciler/internal/hook/hook_test.go

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package hook_test
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223
"reflect"
2324
"strings"
@@ -130,8 +131,8 @@ var _ = Describe("Hook", func() {
130131
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
131132
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
132133
Expect(c.WatchCalls).To(HaveLen(2))
133-
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeNil())
134-
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeNil())
134+
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(Succeed())
135+
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(Succeed())
135136
})
136137

137138
Context("when the owner is cluster-scoped", func() {
@@ -153,8 +154,8 @@ var _ = Describe("Hook", func() {
153154
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
154155
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
155156
Expect(c.WatchCalls).To(HaveLen(2))
156-
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeNil())
157-
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeNil())
157+
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(Succeed())
158+
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(Succeed())
158159
})
159160
It("should watch cluster-scoped resources with ownerRef handler", func() {
160161
rel = &release.Release{
@@ -163,8 +164,8 @@ var _ = Describe("Hook", func() {
163164
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
164165
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
165166
Expect(c.WatchCalls).To(HaveLen(2))
166-
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeNil())
167-
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeNil())
167+
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(Succeed())
168+
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(Succeed())
168169
})
169170
It("should watch resource policy keep resources with annotation handler", func() {
170171
rel = &release.Release{
@@ -173,10 +174,10 @@ var _ = Describe("Hook", func() {
173174
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
174175
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
175176
Expect(c.WatchCalls).To(HaveLen(4))
176-
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeNil())
177-
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeNil())
178-
Expect(validateSourceHandlerType(c.WatchCalls[2].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeNil())
179-
Expect(validateSourceHandlerType(c.WatchCalls[3].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeNil())
177+
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(Succeed())
178+
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(Succeed())
179+
Expect(validateSourceHandlerType(c.WatchCalls[2].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(Succeed())
180+
Expect(validateSourceHandlerType(c.WatchCalls[3].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(Succeed())
180181
})
181182
})
182183

@@ -200,7 +201,7 @@ var _ = Describe("Hook", func() {
200201
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
201202
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
202203
Expect(c.WatchCalls).To(HaveLen(1))
203-
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeNil())
204+
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(Succeed())
204205
})
205206
It("should watch cluster-scoped resources with annotation handler", func() {
206207
rel = &release.Release{
@@ -209,7 +210,7 @@ var _ = Describe("Hook", func() {
209210
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
210211
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
211212
Expect(c.WatchCalls).To(HaveLen(1))
212-
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeNil())
213+
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(Succeed())
213214
})
214215
It("should watch namespace-scoped resources in a different namespace with annotation handler", func() {
215216
rel = &release.Release{
@@ -218,7 +219,7 @@ var _ = Describe("Hook", func() {
218219
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
219220
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
220221
Expect(c.WatchCalls).To(HaveLen(1))
221-
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeNil())
222+
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(Succeed())
222223
})
223224
It("should watch resource policy keep resources with annotation handler", func() {
224225
rel = &release.Release{
@@ -227,9 +228,9 @@ var _ = Describe("Hook", func() {
227228
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
228229
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
229230
Expect(c.WatchCalls).To(HaveLen(3))
230-
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeNil())
231-
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeNil())
232-
Expect(validateSourceHandlerType(c.WatchCalls[2].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeNil())
231+
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(Succeed())
232+
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(Succeed())
233+
Expect(validateSourceHandlerType(c.WatchCalls[2].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(Succeed())
233234
})
234235
It("should iterate the kind list and be able to set watches on each item", func() {
235236
rel = &release.Release{
@@ -238,8 +239,8 @@ var _ = Describe("Hook", func() {
238239
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
239240
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
240241
Expect(c.WatchCalls).To(HaveLen(2))
241-
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeNil())
242-
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeNil())
242+
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(Succeed())
243+
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(Succeed())
243244
})
244245
It("should error when unable to list objects", func() {
245246
rel = &release.Release{
@@ -254,17 +255,49 @@ var _ = Describe("Hook", func() {
254255
})
255256
})
256257

258+
var _ = Describe("validateSourceHandlerType", func() {
259+
It("should return an error when source.Source is nil", func() {
260+
Expect(validateSourceHandlerType(nil, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(HaveOccurred())
261+
})
262+
It("should return an error when source.Kind.Handler is nil", func() {
263+
Expect(validateSourceHandlerType(source.Kind(nil, &unstructured.Unstructured{}, nil, nil), &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(HaveOccurred())
264+
})
265+
It("should return an error when expected is nil", func() {
266+
Expect(validateSourceHandlerType(source.Kind(nil, &unstructured.Unstructured{}, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{}, nil), nil)).To(HaveOccurred())
267+
})
268+
It("should return an error when source.Kind.Handler does not match expected type", func() {
269+
Expect(validateSourceHandlerType(source.Kind(nil, &unstructured.Unstructured{}, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{}, nil), "string")).To(HaveOccurred())
270+
})
271+
It("should not return an error when source.Kind.Handler matches expectedType", func() {
272+
Expect(validateSourceHandlerType(source.Kind(nil, &unstructured.Unstructured{}, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{}, nil), &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(Succeed())
273+
})
274+
})
275+
257276
// validateSourceHandlerType takes in a source.Source and uses reflection to determine
258277
// if the handler used by the source matches the expected type.
259278
// It is assumed that the source.Source was created via the source.Kind() function.
260279
func validateSourceHandlerType(s source.Source, expected interface{}) error {
280+
if s == nil {
281+
return errors.New("nil source.Source provided")
282+
}
261283
sourceVal := reflect.Indirect(reflect.ValueOf(s))
284+
if !sourceVal.IsValid() {
285+
return errors.New("provided source.Source value is invalid")
286+
}
262287
handlerFieldVal := sourceVal.FieldByName("Handler")
263-
288+
if !handlerFieldVal.IsValid() {
289+
return errors.New("provided source.Source's Handler field is invalid")
290+
}
264291
handlerField := reflect.Indirect(handlerFieldVal.Elem())
292+
if !handlerField.IsValid() {
293+
return errors.New("provided source.Source's Handler field value is invalid")
294+
}
265295
handlerType := handlerField.Type()
266296

267297
expectedValue := reflect.Indirect(reflect.ValueOf(expected))
298+
if !expectedValue.IsValid() {
299+
return errors.New("provided expected value is invalid")
300+
}
268301

269302
expectedType := expectedValue.Type()
270303
if handlerType != expectedType {

0 commit comments

Comments
 (0)