Skip to content

Commit

Permalink
use reflection for comparing handler types
Browse files Browse the repository at this point in the history
Signed-off-by: everettraven <everettraven@gmail.com>
  • Loading branch information
everettraven committed May 17, 2024
1 parent a09a349 commit 7572d45
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions pkg/reconciler/internal/hook/hook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package hook_test

import (
"context"
"fmt"
"reflect"
"strings"

"github.com/go-logr/logr"
Expand All @@ -30,10 +32,13 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/cache/informertest"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/source"

"github.com/operator-framework/helm-operator-plugins/pkg/hook"
"github.com/operator-framework/helm-operator-plugins/pkg/internal/fake"
internalhook "github.com/operator-framework/helm-operator-plugins/pkg/reconciler/internal/hook"
sdkhandler "github.com/operator-framework/operator-lib/handler"
)

var _ = Describe("Hook", func() {
Expand Down Expand Up @@ -124,6 +129,8 @@ var _ = Describe("Hook", func() {
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
Expect(c.WatchCalls).To(HaveLen(2))
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeTrue())
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeTrue())
})

Context("when the owner is cluster-scoped", func() {
Expand All @@ -145,6 +152,8 @@ var _ = Describe("Hook", func() {
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
Expect(c.WatchCalls).To(HaveLen(2))
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeTrue())
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeTrue())
})
It("should watch cluster-scoped resources with ownerRef handler", func() {
rel = &release.Release{
Expand All @@ -153,6 +162,8 @@ var _ = Describe("Hook", func() {
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
Expect(c.WatchCalls).To(HaveLen(2))
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeTrue())
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeTrue())
})
It("should watch resource policy keep resources with annotation handler", func() {
rel = &release.Release{
Expand All @@ -161,6 +172,10 @@ var _ = Describe("Hook", func() {
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
Expect(c.WatchCalls).To(HaveLen(4))
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeTrue())
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeTrue())
Expect(validateSourceHandlerType(c.WatchCalls[2].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeTrue())
Expect(validateSourceHandlerType(c.WatchCalls[3].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeTrue())
})
})

Expand All @@ -184,6 +199,7 @@ var _ = Describe("Hook", func() {
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
Expect(c.WatchCalls).To(HaveLen(1))
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeTrue())
})
It("should watch cluster-scoped resources with annotation handler", func() {
rel = &release.Release{
Expand All @@ -200,6 +216,7 @@ var _ = Describe("Hook", func() {
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
Expect(c.WatchCalls).To(HaveLen(1))
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeTrue())
})
It("should watch resource policy keep resources with annotation handler", func() {
rel = &release.Release{
Expand All @@ -208,6 +225,9 @@ var _ = Describe("Hook", func() {
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
Expect(c.WatchCalls).To(HaveLen(3))
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeTrue())
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeTrue())
Expect(validateSourceHandlerType(c.WatchCalls[2].Source, &sdkhandler.EnqueueRequestForAnnotation[*unstructured.Unstructured]{})).To(BeTrue())
})
It("should iterate the kind list and be able to set watches on each item", func() {
rel = &release.Release{
Expand All @@ -216,6 +236,8 @@ var _ = Describe("Hook", func() {
drw = internalhook.NewDependentResourceWatcher(c, rm, cache, sch)
Expect(drw.Exec(owner, *rel, log)).To(Succeed())
Expect(c.WatchCalls).To(HaveLen(2))
Expect(validateSourceHandlerType(c.WatchCalls[0].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeTrue())
Expect(validateSourceHandlerType(c.WatchCalls[1].Source, handler.TypedEnqueueRequestForOwner[*unstructured.Unstructured](sch, rm, owner, handler.OnlyControllerOwner()))).To(BeTrue())
})
It("should error when unable to list objects", func() {
rel = &release.Release{
Expand All @@ -230,6 +252,23 @@ var _ = Describe("Hook", func() {
})
})

// validateSourceHandlerType takes in a source.Source and uses reflection to determine
// if the handler used by the source matches the expected type.
// It is assumed that the source.Source was created via the source.Kind() function.
func validateSourceHandlerType(s source.Source, expected interface{}) bool {
sourceVal := reflect.Indirect(reflect.ValueOf(s))
handlerFieldVal := sourceVal.FieldByName("Handler")

handlerField := reflect.Indirect(handlerFieldVal.Elem())
handlerType := handlerField.Type()

expectedValue := reflect.Indirect(reflect.ValueOf(expected))

expectedType := expectedValue.Type()
fmt.Println("XXX DEBUG", handlerType, expectedType, handlerType == expectedType)
return handlerType == expectedType
}

var (
rsOwnerNamespace = `
apiVersion: apps/v1
Expand Down

0 comments on commit 7572d45

Please sign in to comment.